原创 fpga基础 定点小数运算

2011-5-10 21:20 4520 8 11 分类: FPGA/CPLD

       所谓定点小数,就是小数点的位置是固定的。我们是要用整数来表示定点小数,由于小数点的位置是固定的,所以就没有必要储存它(如果储存了小数点的位置,那就是浮点数了)。既然没有储存小数点的位置,那么计算机当然就不知道小数点的位置,所以这个小数点的位置是我们写程序的人自己需要牢记的。

        先以10进制为例。如果我们能够计算12+34=46的话,当然也就能够计算1.2+3.4 或者 0.12+0.34了。所以定点小数的加减法和整数的相同,并且和小数点的位置无关。乘法就不同了。 12*34=408,而1.2*3.4=4.08。这里1.2的小数点在第1位之前,而4.08的小数点在第2位之前,小数点发生了移动。所以在做乘法的时候,需要对小数点的位置进行调整?!可是既然我们是做定点小数运算,那就说小数点的位置不能动!!怎么解决这个矛盾呢,那就是舍弃最低位。 也就说1.2*3.4=4.1,这样我们就得到正确的定点运算的结果了。所以在做定点小数运算的时候不仅需要牢记小数点的位置,还需要记住表达定点小数的有效位数。

        上面这个例子中,有效位数为2,小数点之后有一位。现在进入二进制。我们的定点小数用16位二进制表达,最高位是符号位,那么有效位就是15位。小数点之后可以有0 - 15位。我们把小数点之后有n位叫做Qn,例如小数点之后有12位叫做Q12格式的定点小数,而Q0就是我们所说的整数。 Q12的正数的最大值是 0 111 . 111111111111,第一个0是符号位,后面的数都是1,那么这个数是十进制的多少呢,很好运算,就是 0x7fff / 2^12 = 7.999755859375。对于Qn格式的定点小数的表达的数值就它的整数值除以2^n。在计算机中还是以整数来运算,我们把它想象成实际所表达的值的时候,进行这个运算。反过来把一个实际所要表达的值x转换Qn型的定点小数的时候,就是x*2^n了。例如 0.2的Q12型定点小数为:0.2*2^12 = 819.2,由于这个数要用整数储存, 所以是819 即 0x0333。因为舍弃了小数部分,所以0x0333不是精确的0.2,实际上它是819/2^12 =0.199951171875。

         我们用数学表达式做一下总结: x表示实际的数(*一个浮点数), q表示它的Qn型定点小数(一个整数)。

        q = (int) (x * 2^n) x = (float)q/2^n

由以上公式我们可以很快得出定点小数的+-*/算法:

        假设q1,q2,q3表达的值分别为x1,x2,x3 q3 = q1 + q2

         若 x3 = x1 + x2 q3 = q1 - q2 若 x3 = x1 - x2 q3 = q1 * q2 / 2^n

        若 x3 = x1 * x2 q3 = q1 * 2^n / q2若 x3 = x1 / x2 我们看到加减法和一般的整数运算相同,而乘除法的时候,为了使得结果的小数点位不移动,对数值进行了移动。

        用c语言来写定点小数的乘法就是: short q1,q2,q3; .... q3=((long q1) * (long q2)) >> n; 由于/ 2^n和* 2^n可以简单的用移位来计算,所以定点小数的运算比浮点小数要快得多。

        下面我们用一个例子来验证一下上面的公式:用Q12来计算2.1 * 2.2,先把2.1 2.2转换为Q12定点小数: 2.1 * 2^12 = 8601.6 = 8602 2.2 * 2^12 = 9011.2 = 9011 (8602 * 9011) >> 12 = 18923 18923的实际值是18923/2^12 = 4.619873046875 和实际的结果 4.62相差0.000126953125,对于一般的计算已经足够精确了。

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1842007 2016-3-21 21:02

看完你这篇博文 终于才是对定点数开始理解了 特别是例子 让人醍醐灌顶

用户324891 2014-7-24 20:48

不错,谢谢楼主这篇文章。

用户377235 2014-1-18 09:35

定点数和小数的换算

相关推荐阅读
用户1631420 2011-12-06 08:42
改版了!
很久很久没上edn了~ 改版了,有点不习惯了。 很多事情冲着我来了。可能是每个这个年龄段的人都会遇到的 我不知道我处理的好不好。但我还是按照我的意志去做了。 工作上的事情 突如其来...
用户1631420 2011-07-17 14:08
基于FPGA的PID算法实现
    有段时间没来这里写东西。最近稍微有些忙,工程硕士报名了,又有一部分时间给它了。     言归正传,之前一直在学习PID算法,最近再用FPGA来实现PID控制,目前进行的2个实践一个,一个是温 ...
用户1631420 2011-06-05 12:12
基于ds18b20 的fpga 温度计
作为恒温控制系统选择的前端温度测量模块,ds18b20的控制相对麻烦点,相关ds18b20的资料可以查看手册。 整体模块划分   pll分频模块,25mhz晶振 倍到50 mhz在分频1mhz,1us...
用户1631420 2011-06-02 17:22
随便聊聊~
       年也过完了,2010年对于我自己来说风起云涌,变化不测啊~       今年27了,一事无成。偶然之间在单位图书馆翻到一本fpga的杂志,颇有兴趣,于是找到了这里。      申请用户,...
用户1631420 2011-05-26 13:33
fpga设计流程图
...
用户1631420 2011-05-26 12:47
for循环与阻塞赋值
   阻塞赋值和非阻塞赋值是verilog里一个难点,也是重点,相关区别各大论坛博客里都有详细的讲解。       先说几个经验上的要点。       在时序逻辑里都采用非阻塞赋值,在组合逻辑里采用阻...
我要评论
3
8
关闭 站长推荐上一条 /3 下一条