FPGA技术交流群:838607138
在算法中经常会出现小数,而在FPGA上处理小数是一件极其耗费资源的操作,甚至可以说在硬件平台上0 1这种表示方式天生就对小数不友好。那么就衍生出来了不同的表示方法,主要分为两种:
- 定点数
- 浮点数
浮点数有著名的IEEE754标准,他将数分为了指数,尾数和符号位。这个就不多说了,有兴趣可以查查。今天的重点是定点数的表示。
定点数就是小数点固定的数,比如采用16bit的数据,其中低8位是小数,高8位是整数。这样我们就把小数点固定到8位上了。如下图所示15到8bit是整数位,7到0bit是小数位。(中间的橙色方块表示小数点,因为我们固定了小数点的位置,所以不需要单独的1bit来表示小数点,因此下面画的图虽然是17个格子,但仍然是16bit),为了下面描述方便,我们采用P-Q这样一个表示法,P代表整数位数,Q表示小数位数,所以下面这个示例就记作8-8。
那么知道怎么表示定点数了,我们来介绍一下精度问题。这个精度就等于1/2Q,Q代表小数的位数。以上面这个Q是8为例,精度就是1/28=0.00390625。
那么2.5用8-8这样表示为00000010_10000000,其中00000010为整数2,10000000为小数0.5 。0.5/0.00390625=128,128表示为2进制的10000000。
知道了怎么表示定点数,下步就来介绍一下运算规则,以a,b代表浮点数,x,y代表相应的定点数,并且小数点为n位,即Q=n。
-
a + b = x + y
-
a - b = x - y
-
a * b = x * y /(2^n)
-
a / b = x / y * (2^n)
加减好理解,以乘法为例说明为什么需要有2^n参与运算。为了表示方便就以10进制为例,2.5*3.1=7.75,也就是原来都是1位小数,相乘后变成两位小数了,但是由于我们的小数点位数是固定的,所以需要移动小数点变成7.7或者7.8,取决于round的实现方法。
计算方法也有了,这个用verilog实现也不困难,主要是需要细心,不要把在进行饱和截位的时候弄错bit数。