数字递归平方根

时间:2015-06-19 09:39:45

标签: algorithm floating-point numerical-methods

我需要为通用浮点格式实现数字递归平方根,这样exp_size + mant_size + 1< = 64。

我基本上遵循了此处建议的实施 handbook of floating point arithmetic在浮点运算符的软件实现中。

我试图测试我的实现(不是详尽的测试),基本上对于像32位这样的格式看起来工作正常,而对于像mantissa = 10这样的格式,exponent = 5表示输入x = 0.25相反给我0.5它显然给我0.707031。

所以,如果对于小格式,可能数字递归方法有一些限制或者......或者只是我的实现很糟糕...

我希望你能帮助我......从0开始实施这些东西很痛苦......

1 个答案:

答案 0 :(得分:0)

查看代码非常困难,但您应该:

  1. 测试所有操作数组合

    • 如果它适用于单个示例并不意味着它适用于所有这些
  2. 检查位掩码

    • 你在使用32bit时写的那么结果很好
    • 当使用10然后
    • 暗示某处溢出
    • 您确定您为R保留/屏蔽了正确的位数吗?
    • R应比Q高2位(精度为+1位,符号为+1位)
    • 并且你应该处理R作为补充
    • Q是D位的一半且无符号
  3. 无法找到你的算法(你链接的那本书不允许我进一步,那么SQRT启动的第265页可能有些不兼容我使用好的旧Opera)但这是我在Google中找到的最接近的一种(非恢复-SQRT) )在FPGA上的一些PDF研究和硬件实现中,在清除错误和测试之后,这就是我在C ++中编写代码并进行测试的:

    DWORD u32_sqrt(DWORD D) // 32bit
        {
        const int   _bits  =32;
        const DWORD _R_mask=(4<<(_bits>>1))-1;
        const DWORD _R_sign= 2<<(_bits>>1);
        DWORD Q=0; // u(_bits/2    ) result (quotient)
        DWORD R=0; // i(_bits/2 + 2) 2os complement (remainder) R=D-Q*Q
        for (int i=_bits-2;i>=0;i-=2)
            {
            if (DWORD(R&_R_sign)){ R=(R<<2)|((D>>i)&3); R+=(Q<<2)|3; }  // R< 0
             else                { R=(R<<2)|((D>>i)&3); R-=(Q<<2)|1; }  // R>=0
            R&=_R_mask; Q<<=1; if (!DWORD(R&_R_sign)) Q|=1;             // R>=0
            }
        return Q;
        }