zoukankan      html  css  js  c++  java
  • 关于小数计算引发的定点数思考

    在写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。

  • 相关阅读:
    Codeforces 963A Alternating Sum 【数论+数学】
    大数相加 a+b
    BFS(广度优先搜索) poj3278
    PHPExcel 学习笔记
    一个高在线(可以超过1024)多线程的socket echo server(pthreads 和 libevent扩展)
    php pthreads 多线程扩展的使用:一个较为稳定例子。
    PHP 长字符串替换操作性能(替换多换注释的代码)
    最简单的PHP socket echo server。
    PHP 多线程扩展(正儿八经的线程)pthreads安装
    定长度结构体数组、不定长度结构体指针初始化
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/8735926.html
Copyright © 2011-2022 走看看