为什么我需要在对结果求和之前左移?
Why do i need to left shift before summing the result?
这是一个按预期工作的代码片段,它正确地反转了整数的位和 returns 新的 int。我的问题是为什么 result <<= 1
行必须出现在我用操作 n&1
?
求和结果之前
在第一次迭代中,它不会影响结果,因为结果被实例化为 0。如果我将 result <<= 1
行放在 for 循环的末尾,我仍然会在我之前移动结果将结果与 n&1
相加。
我的代码(最后是左移结果)无法正常工作,我似乎无法理解这最后一步。
public int reverseBits(int n) {
int result = 0;
for(int i=0; i<32; i++){
result <<= 1;
result += n&1;
n >>= 1;
}
return result;
}
因为否则你操作错误的位。请注意,如果有帮助,您可以用简单的算术和除法替换当前的移位。喜欢,
public static int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result += result + (n & 1);
n /= 2;
}
return result;
}
解释1:
result <<= 1;
等同于result = result * 2
,与result = result + result
相同,可以结合下一条指令;
result += n&1
并得到
result += result + (n & 1);
至于>>= 1
,与/ 2
相同。
1数学.
在第一次迭代中它确实没有效果,但没关系,这是故意的。它比写 if (i != 0) result <<= 1;
更好。在每次迭代中检查它是低效的。但同样重要的是要注意这一点,基本上在 32 次迭代中,只有在 31 次迭代中它才会有效果并且应该。因此,如果您将 result <<= 1;
行放在末尾,则要确保它仅有效执行 31 次,同时请记住,现在它应该在顺序更改后的第一次迭代中执行,但不应在最后一次迭代中执行迭代。这就是结果无效的原因。
试试这个。这会起作用。
public int reverseBits(int n) {
int result = 0;
for(int i=0; i<32; i++){
result += n&1;
n >>= 1;
if (i != 31) // skip the shift in last iteration
result <<= 1;
}
return result;
}
这是一个一次性问题:
- 你需要复制 32 位,所以你要执行 32
result += n&1;
操作 (0..31)
- 要将最右边的位(位置0)移动到最左边的位置(位置31)只需要进行31次左移操作。
因此,将 result <<= 1;
放在开头是可以的,因为它实际上什么也不做,因为 result
中还没有任何内容,所以您只进行了 31 次左移。
仅当您在 result += n&1;
之后移动它时,您才进行 32 次左移操作,丢失一位。
n >>= 1;
也是如此,您也执行 32 次右移操作,但最后的右移并不重要,因为它永远不会添加到结果中(无论如何都是零)。
这是一个按预期工作的代码片段,它正确地反转了整数的位和 returns 新的 int。我的问题是为什么 result <<= 1
行必须出现在我用操作 n&1
?
在第一次迭代中,它不会影响结果,因为结果被实例化为 0。如果我将 result <<= 1
行放在 for 循环的末尾,我仍然会在我之前移动结果将结果与 n&1
相加。
我的代码(最后是左移结果)无法正常工作,我似乎无法理解这最后一步。
public int reverseBits(int n) {
int result = 0;
for(int i=0; i<32; i++){
result <<= 1;
result += n&1;
n >>= 1;
}
return result;
}
因为否则你操作错误的位。请注意,如果有帮助,您可以用简单的算术和除法替换当前的移位。喜欢,
public static int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result += result + (n & 1);
n /= 2;
}
return result;
}
解释1:
result <<= 1;
等同于result = result * 2
,与result = result + result
相同,可以结合下一条指令;
result += n&1
并得到
result += result + (n & 1);
至于>>= 1
,与/ 2
相同。
1数学.
在第一次迭代中它确实没有效果,但没关系,这是故意的。它比写 if (i != 0) result <<= 1;
更好。在每次迭代中检查它是低效的。但同样重要的是要注意这一点,基本上在 32 次迭代中,只有在 31 次迭代中它才会有效果并且应该。因此,如果您将 result <<= 1;
行放在末尾,则要确保它仅有效执行 31 次,同时请记住,现在它应该在顺序更改后的第一次迭代中执行,但不应在最后一次迭代中执行迭代。这就是结果无效的原因。
试试这个。这会起作用。
public int reverseBits(int n) {
int result = 0;
for(int i=0; i<32; i++){
result += n&1;
n >>= 1;
if (i != 31) // skip the shift in last iteration
result <<= 1;
}
return result;
}
这是一个一次性问题:
- 你需要复制 32 位,所以你要执行 32
result += n&1;
操作 (0..31) - 要将最右边的位(位置0)移动到最左边的位置(位置31)只需要进行31次左移操作。
因此,将 result <<= 1;
放在开头是可以的,因为它实际上什么也不做,因为 result
中还没有任何内容,所以您只进行了 31 次左移。
仅当您在 result += n&1;
之后移动它时,您才进行 32 次左移操作,丢失一位。
n >>= 1;
也是如此,您也执行 32 次右移操作,但最后的右移并不重要,因为它永远不会添加到结果中(无论如何都是零)。