基于FPGA的数字信号处理(4)--浮点数的定点化

devtools/2024/9/23 5:15:08/

写在前面

首先要说明的是,题目《浮点数定点化》中所谓的 浮点数 并不是指 IEEE754 规定的 单精度浮点数 或者 双精度浮点数 等格式,而是指10进制小数。所以说白了,这篇文章要讲的就是如何将10进制小数采用定点数的形式表示。


为什么2进制无法精准地表示10进制小数?

你在学习进制转换时,有没有关注过这样一个问题:

为什么10进制小数转成2进制小数的题目通常都会规定有效位数?

例如:将10进制数 0.1 转换为 2进制小数,要求小数有效位数为5位。按照转换方法–乘2直到小数部分为0即可。

那么 0.1(D)= 0.0001100110011····,这时你就会发现,这个乘法过程似乎可以一直持续下去,但是好在题目只要求到小数点后5位,所以结果是 0.00011

这能说明一个问题:10进制数 0.1 没办法被2进制精准地表示。不过某些小数,在特定的位宽下是可以被2进制精准表示的,比如:

0.5(D)= 0.1(B)

0.25(D)= 0.01(B)

0.875(D)= 0.111(B)

Why?

整数的2进制表示却没有这个问题,只要不限制位宽,那10进制整数一定可以被2进制精准表示,比如:

17(D)用4位2进制数无法表示,因为它的最大范围是4’b1111即15,但可以被5位及更多位的2进制数表示。

关于这一点可以从两个方面去理解:

  1. 整数是离散的,在固定范围内整数的个数是固定的,比如在0~15范围内那必然只有16个整数;而小数是连续的,在固定范围内小数的个数是无限。不管采用定点数还是浮点数的形式,那都是在用有限的编码个数来表示无限的小数,所以某些小数必然无法精准表示。
  2. 2进制整数的最小单位是最低位,即10进制的 “1”,所以整串数字可以看做是数个 “1” 的和,而显然任何整数都可以被 “1” 整除。但小数的2进制表示的最小单位是随着位宽而变化的,比如1位小数的最小单位是0.5,2位小数是0.25。所以不管是几位小数,这些 “最小单位” 都无法做到能整除所有小数。

至此,可以得出结论:并非所有的10进制小数,都可以被2进制数精确表示,在这个进制转换的过程中某些小数一定会存在误差。


浮点数定点数

浮点数转为定点数,也叫做 浮点数定点化

定点化首先需要约定好定点数的规格:**用几位表示整数,用几位表示小数,要不要表示符号位?**这些规格需要根据输入数据的范围和特性而定(这些往往在算法阶段确定)。

假如要输入的数据 a 的范围在 -9~5 之间,要求精度保留5位。那么绝对值最大的| -9 |至少需要用4位(1001)才能表示,所以整数部分为4位。综上,数据 a 的定点化规格应为:符号位1位,整数部分4位,小数部分5位,共10位。

假设a的一个值是 3.1415,那么它的定点化过程如下:

  1. 小数部分5位,则分辨率为2 ^ -5=0.03125。3.1415转化为2进制小数相当于在算需要多少个分辨率小数来表示它,所以转化过程为 3.1415 / 2 ^ -5 = 3.1415 × 2 ^ 5 = 100.528。
  2. 这个结果只能取整数部分,因为二进制小数相对其分辨率来说,只能表示整数个。例如两位小数的分辨率是1/4 = 0.25,那么 0.00-0.11(B)就分别表示0.01(B)即0.25(D)的0-3倍,即0、0.25、0.5、0.75。
  3. 取整的方法有两种:
    1. 直接截去小数部分(truncate),这相当于数学上的向下取整(floor),就电路设计角度而言,截去的实现是很简单的,所以这种方法最为常用;
    2. 四舍五入(round),这样产生的误差比直接截断的误差小,但是需要多余的电路来实现,因此不太常用。
  4. 将结果100.528的小数部分截掉,为 100(D),可以理解为需要100个0.03125才能表示,即3.1415(D) = 100(D) × 0.00001(B),所以只要将100转化为2进制表示即可,即100(D)= 1100100(B)。因为设计的位宽是10位,所以需要补上符号位和在整数部分的高位补0,即最终结果为 0_0011_00100 。

0_0011_00100表示的值为 +3.125,它和原始数之间的差值就是 量化误差,为|3.125 - 3.1415| = 0.0165。量化误差是在量化过程中因为截断或四舍五入所直接产生的,但本质上还是因为有限个2进制编码无法表示无穷个10进制小数。

浮点数乘以2^Q,然后四舍五入或截去小数,就是定点数。其中Q为定标值(以确定小数位数)。


定点数浮点数

还是要先说明,这个浮点数不是IEEE754规定的浮点数,仅指10进制小数,显然这就是定点化逆过程。以 定点数0_0011_00100 的转换为例:

  • 首先需要确定该定点数的规格,假设其规格如下:1位符号位 + 4位整数部分 + 5位小数部分
  • 符号位为0说明这是一个正数
  • 整数部分的值为0011,即10进制的3
  • 小数部分的值为00100,即10进制的0.125(可以理解为0.03125×4)
  • 综合起来的结果就是 +3.125

整个过程相对简单,只要将整数部分和小数部分分别从2进制转换为10进制,再结合起来即可。


http://www.ppmy.cn/devtools/30793.html

相关文章

Springboot的Web开发

Springboot的Web开发 在Spring Boot的Web开发中,有许多支持类和配置文件可以帮助我们快速搭建和配置Web应用程序。其中一些重要的支持类和配置文件包括: ServerPropertiesAutoConfiguration和ServerProperties:这两个类用于配置服务器的相关…

118. 杨辉三角

118. 杨辉三角 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[…

YOLOv5白皮书-第Y6周:模型改进

YOLOv5白皮书-第Y6周:模型改进 YOLOv5白皮书-第Y6周:模型改进一、前言二、我的环境三、更正后的yolov5s.yaml四、运行截图![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/23c3ac6b05d74bfcbea5ec238681710d.png)五、总结 YOLOv5白皮书-第Y6周…

Maven 构建 Flink 应用程序的最佳实践(根除各种类冲突/类加载问题)

作为开发者,在构建 Flink 应用程序时的体验真是一言难尽,想必大家都曾遇到过各种 ClassNotFoundException、NoSuchMethodError 以及 Could not find any factory for identifier kafka/jdbc/hive/hudi that implements org.apache.flink.table.factories.DynamicTableFactory…

LLM 构建Data Multi-Agents 赋能数据分析平台的实践之③:数据分析之二(大小模型协同)

一、概述 随着新一代信息技术在产业数字化中的应用,产生了大量多源多模态信息以及响应的信息处理模式,数据孤岛、模型林立的问题也随之产生,使得业务系统臃肿、信息处理和决策效率低下,面对复杂任务及应用场景问题求解效率低。针…

Vue3使用vue-quill富文本编辑器并实现图片自定义上传替换默认base64格式图片

本文介绍在vue3环境下使用vue-quill富文本编辑器,并实现使用自定义上传接口将图片上传至服务器并保存为img标签src为服务器中图片的地址而不是默认的base64格式图片。从而解决富文本编辑器使用base64导致字段超长问题。 1.安装依赖库 npm install vueup/vue-quill…

Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)

1 漏洞原理 在Apache Tomcat服务器中,PUT方法通常用于上传文件。攻击者可以通过发送PUT请求,将恶意文件上传到服务器。 当攻击者发送PUT请求时,Tomcat服务器会将请求中的数据写入指定的文件。如果攻击者能够控制文件路径,那么他们…

k8s安装nginx Ingress超详细指南

在本全面的 Ingress 指南中,您将学习如何在 Kubernetes 上设置 Nginx Ingress控制器并使用 DNS 配置 Ingress。 目前有两种 Nginx Ingress 控制器。 kubernetes 社区的 Nginx Ingress 控制器Nginx Inc 开发的 Nginx Ingress 控制器 我们将使用 Kubernetes 社区 N…