【问题标题】:What is the fastest way to find integer square root using bit shifts?使用位移求整数平方根的最快方法是什么?
【发布时间】:2012-06-07 15:06:55
【问题描述】:

我正在寻找计算数字(整数)平方根(整数)的最快方法。我在维基百科中遇到了这个解决方案,它找到一个数字的平方根(如果它是一个完美的平方)或它最近的下完美平方的平方根(如果给定的数字不是一个完美的平方:

short isqrt(short num) {
    short res = 0;
    short bit = 1 << 14; // The second-to-top bit is set: 1L<<30 for long
    // "bit" starts at the highest power of four <= the argument.
    while (bit > num)
        bit >>= 2;
    while (bit != 0) {
        if (num >= res + bit) {
            num -= res + bit;
            res = (res >> 1) + bit;
        }
        else
            res >>= 1;
        bit >>= 2;
    }
    return res;
}

我尝试了很多测试运行来跟踪算法,但我似乎不理解 while(bit!=0) 中的部分。谁能给我解释一下这部分?

【问题讨论】:

    标签: bit-shift memory-efficient square-root


    【解决方案1】:

    我也找到了一些小例子,我想我明白了。据我了解,该算法一次构建一个二进制数字的答案,从最高位到最低位。

    让“num_init”为函数开头的num的值。假设在某个迭代中,我们有 bit = 4^x 并且 num 等于某个值“num_curr”(快速浏览一下,直到 bit 为 0,它始终是 4 的幂)。那么 res 的形式为 y*2^(x+1),其中 y^2 + num_curr = num_init,y 小于实际答案,但在 2^x 之内。

    num、res 和 bit 的值的这个不变量将是关键。在代码中这样做的方式是

    while (bit != 0) {
        ....
    }
    

    正在将我们的假想指针从左向右移动,并且在每一步我们都确定该位是 0 还是 1。

    转到第一个 if 语句,假设我们虚构的“累积”整数等于 y,我们正在查看 2^x 位。然后,如果 num 的原始值至少为 (y + 2^x)^2 = y^2 + y*2^(x+1) + 4^x,则该位为 1。换句话说,如果 num 在该点的值至少为 y*2^(x+1) + 4^x,则该位为 1(因为我们有 num 的值下降 y^2 的不变量) .很方便,res = y*2^(x+1) 和 bit = 4^x。然后我们就明白了

    if (num >= res + bit) {
        num -= res + bit;
        res = (res >> 1) + bit;
    }
    else 
        res >>= 1;   
    

    如有必要,它会在我们的想象位置添加一个 1 位,然后更新 res 和 num 以保持不变。最后

    bit >>= 2;
    

    更新位并移动所有内容。

    【讨论】:

      猜你喜欢
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-07
      • 1970-01-01
      相关资源
      最近更新 更多