【发布时间】:2019-04-07 21:31:34
【问题描述】:
我正在努力使用用于计算大数平方根的位移算法。我有 32 位字的数组,输入无关紧要,输出总是相同的数字。以前,该算法在每个数组单元格中使用 1 位,但是当我切换到单元格中的单词时,它不再起作用了。
我编写了完全独立工作的方法(添加单词、减去单词、向右移动位),但整个程序并没有达到我的预期。
当输入数字的第一个位置为 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};
代码:
一个[0] = 1L
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;
}
我无法发现代码中的错误,尤其是当我单独测试所有方法时,它们似乎都有效。
【问题讨论】:
-
请发帖minimal reproducible example。这里没有足够的代码和变量声明来了解发生了什么。 所有方法都有效 不,它们没有。
add_word没有正确计算进位(2 ^ 32是 34,并且您使用的方法由于溢出而不起作用)。 -
@1201ProgramAlarm 是的,我不小心复制了错误版本的
add_word方法。现在我编辑并发布了我正在使用的那个。 -
您可以使用二进制搜索来计算平方根。这将需要
O(log(n))。 -
@AtulKumar 我已经阅读了所有算法并选择了这个,因为一旦它在 c++ 中工作,我将不得不在汇编中编写它,而这个似乎是最容易在汇编中实现的。
标签: c++ algorithm square-root