使用移位算法计算平方根总是输出相同的数字

时间:2019-04-07 21:31:34

标签: c++ algorithm square-root

我正在努力使用位移算法来计算大数的平方根。我有32位字的数组,与输入无关紧要,输出始终是相同的数字。以前,该算法每个数组单元只能使用1位,但是当我切换到单元中的单词时,该算法不再起作用。
我编写了可以完全独立工作的方法(添加单词,减去单词,向右移动位),但是整个程序并没有达到我的期望。
当输入数字的第一个位置为0时,输出为0,当输入数字为0时,但数组的第一个单元格不为0,则输出始终相同。

变量:

uint32_t var[4] = {0,0,0,0};
uint32_t w_number[word_len] = {1, 0,0,234324};
uint32_t one[word_len]      = {0,0,0,0};
uint32_t var[word_len]      = {0,0,0,0};
uint32_t buff[word_len]     = {0,0,0,0};
uint32_t result[word_len]   = {0,0,0,0};

代码:

one [0] = 1L << 30;

while (isBigger(one, input))
{
    shiftR_word(one);
    shiftR_word(one);
}

while (!isZero(one))
{
    add_word(result, one, var); //the result of one+result is put in Var. 

    if ((isBigger(input, var) || equals(input, var))) // if (input >= var) 
    {       
        subtract_word(input, var, input); // input-=var
        shiftR_word(result);
        add_word(result, one, result);          
    }
    else
    {
        shiftR_word(result);            
    }
    shiftR_word(one);
    shiftR_word(one);
}

std::cout << "\nOut: ";
printAsBit(result);
std::cout << std::endl;

这是我使用的移位算法,可能会引起问题。

    void shiftR_word(uint32_t w_number[], int n=4)
    {
      // n - how many words
      //(n*32b word) >> 1
      bool* odd = new bool[n];

        for (int i = 0; i < n; i++)
        {
          if( w_number[i] & 1 )
            odd[i]=true;
          else
            odd[i]=false;
        }


        for (int i = 0; i < n; i++)
          w_number[i] >>= 1;

        for (int i = 0; i <= n-1; i++)
        {
          if(odd[i])
          {
            w_number[i+1] = w_number[i+1] | 1 << 31;
          }
        }

      delete[] odd;
    }

添加功能:

void add_word(uint32_t a[], uint32_t b[], uint32_t result[], int len=4)
{
  int carry=0;

  for (int i = len-1; i >=0; i--)
  {
    result[i]=a[i]+b[i]+carry;
    carry = (a[i]>result[i] || b[i]>result[i]) ? 1 : 0;

  } 
}

isBigger方法:

bool isBigger(uint32_t a[],uint32_t b[] ,int len=4)
{
    for (int i = 0; i < len; i++)
    {
      if (a[i]>b[i])
      {
        return true;
      }
    }
    return false;
}

我无法在代码中发现错误,尤其是当我分别测试它们时,所有方法似乎都可以工作。

1 个答案:

答案 0 :(得分:0)

sigma.ewma(r.0.94) 不起作用。如果isBigger的{​​2,5}({2,5})和a的{​​6,3}(长度2)值将在返回false时返回b。在循环内部,如果true要返回false,并且仅在两个值相等时才检查下一个值。

a[i] < b[i]

此外,bool isBigger(const uint32_t a[], const uint32_t b[], int len = 4) { for (int i = 0; i < len; i++) { if (a[i] > b[i]) return true; if (a[i] < b[i]) return false; } // Only get here if `a` and `b` are equal return false; } 具有未定义的行为,因为shiftR_word可以超出数组的结尾(当w_number[i+1]时,您将访问i == n-1或{{1} }。在这种情况下,您的循环条件应为w_number[n - 1 + 1]。但是,该功能效率很低。可以将其重写为只需要一个循环而无需分配内存,但这留给读者练习。