我有以下问题:给定一个以base为单位的输入(输入是以该base中的数字数组的形式给出的),将数字的取反写成"base's"-outDigits中的补码表示法。
数的"底数补码"表示法是"二进制补码"的推广:如果我们将(-x)作为一个无符号数处理,并将它加到x上,我们应该得到0(modulo base ^digit-size)。我不能调用其他函数(甚至Math. pow)
我的测试一直出错。我的代码:
public static void baseNegate(int base, int[] inDigits, int[] outDigits) {
outDigits[0] = 1;
for (int i = outDigits.length - 1; i >= 0; i--) {
outDigits[i] += base - (1 + inDigits[i]);
if (i < outDigits.length - 1) {
outDigits[i + 1] = outDigits[i] / base;
}
outDigits[i] %= base;
}
}
我找不到我的计算错误,请帮助。我的测试:
------------------------------------ Negate number 365 in base 10 ------------------------------------
Test case have FAILED.
Base: 10
Input number: [5, 6, 3]
Expected: [5, 3, 6]
Output: [5, 0, 0]
-------------------------------- Negate number b1010110011 in base 2 --------------------------------
Test case have FAILED.
Base: 2
Input number: [1, 1, 0, 0, 1, 1, 0, 1, 0, 1]
Expected: [1, 0, 1, 1, 0, 0, 1, 0, 1, 0]
Output: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-------------------------------------- Negate 0x7AF0 in base 16 --------------------------------------
Test case have FAILED.
Base: 16
Input number: [0, 15, 10, 7]
Expected: [0, 1, 5, 8]
Output: [0, 1, 0, 0]
3条答案
按热度按时间2guxujil1#
你的问题是,你可能看起来在计算补码时试图对补码求反,这使你的解决方案变得复杂。
您可以尝试将解决方案分为两个阶段来简化它:
以下方法是此方法的工作版本:
这种方法更清晰,性能更好,并且代码是自解释的;但我在代码中添加了注解以遵循所使用的逻辑。
Complete code on GitHub
u4dcyp6a2#
由于“期望”值显示索引0是最低位数,这意味着对于数字
123₁₀
,数组将是[3, 2, 1]
,即数字的顺序与你对人的期望相反。对于计算机来说,索引i
处的值是必须乘以baseⁱ
的值是有意义的。这意味着你需要
i
循环向上迭代,而不是向下迭代,这样你就可以跟踪结转。就个人而言,这样写更有意义,特别是因为它不依赖于
outDigits
数组被预初始化为全0:为了获得更好的性能,您不希望使用
%
和/
,因此类似下面的代码可能更好:所有3个将给予相同的结果:
zhte4eai3#
我觉得这里有个问题:
假设您使用基数10。由于数字只能是0到9,所以除以10意味着计算结果始终为0。我认为您不是故意的。