在写CORIC算法实现代码的时候,遇到了小数问题如下:
、
第31行的代码如下:
这说明了写成小数形式,不会通过编译器的检查(暂且叫做编译器),编译器无法识别这种小数的表示方法。但我们又确实需要进行小数的计算,比如加法的;
比如1.4567+2.34789。编译都无法编译,那么该如何计算呢?
我们知道,比如编译器能够识别并计算145670+234789=380459。那么很自然的想到了将380459左移5位,不就得到我们想要的结果3.80459了吗?
这提供给了我们这样的一个原始的思路:将我们 要计算的数先扩大很多倍,变成整数,进行加减(假设也包括了乘除)运算,再将结果缩小同样的倍数,那么就得到我们要的结果。
即我们进行1.4567*10^5+2.34789*10^5=380459,再进行380459÷10^5.就得到了我们想要的结果。这已经是定点数表示的雏形了,但还不够完善,还需要解决两个问题:
1.我们究竟该乘10的多少次方?计算机的计算限制也不允许我们乘的太大了。假设我的计算机很low,只能×10^4.则会得到:
14567+23479=38046(注意,计算机可不会什么四舍五入,只会硬邦邦的算!),38046÷10^4=3.8046;
我们发现,由于计算机很low,导致了我们的计算结果不够精确,但是和原来很接近!!
假设计算机更low,只能扩大10^3,发生了下面的事情:
1456+2347=3803, 3803÷10^3=3.803;
我们发现,结果的精度进一步降低了,如果我们扩大的倍数比较小的话。
上述试验反应了如下问题:我们确实可以通过将所有的小数扩大X倍转化成整数,进行加减,再÷X倍,就能得到我们要求解的数,而且扩大的倍数比较大的时候,得到的结果较为精确。
2 乘以10^n真的好吗?
定点数都是×2^n,为啥不是10^n呢,不是更直观吗?请注意,最后总要进行除法运算,得到我们想要得到的东西,但是除以10^n需要动用乘法器!!!或者我们自己设计一个复杂的算法,但是÷2^n就很简单,直接进行右移n位即可。因此,我们选择将一个数×2^n这样的操作。
这就是定点加法的本质(乘法之后再讨论),关于为什么叫做定点,因为小数点的位置是固定的,不需要硬件进行考虑的。通过我们扩大小数变成整数可以看出来,我们可以理解为小数点的位置在整数的最右端。即小数点的位置固定在整数的个位右边,至此完成了对定点数的完整分析,之后进行FPGA定点数(多是小数)计算以及DSP的定点计算的时候,在数值初始化的时候,务必不要忘了要进行×2^n这种操作!!主要原因在于没有操作系统!!!!!!!!没法优化小数
下面附一张示例图供以后参考:
这个图同时也告诉我们了Verilog中进行宏定义(假设是这么叫)的做法!!!!假设我们要使用某个变量,比如rot1,则为 : `rot1。