我在这里面临的问题是理解循环的每一次迭代中n值的变化。
如果你用2-3次迭代来解释它,那就太棒了。校正-return值应为32位,....which正在改变所有位数0->1 ans 1->0。
long fun(long n)
{
for(int i = 0; i < 32; i++)
n = n ^ 1U << i;
return n;
} 发布于 2020-07-21 15:26:05
i在数数。
1U << i是一个单独的无符号位(LSB),它在i向左的每一个回合中被移动,即它扫描位位置,0001,0010,0100,1000 (请读为二进制)。
n = n ^ 1U << i将n设置为n和移位位的异或。也就是说,它一点一点地对n进行了扩展。
结果是一个完全倒置的n。
让我们看一下示例13,1101上的4次二进制迭代。
1101 ^ 0001 is 1100
1100 ^ 0010 is 1110
1110 ^ 0100 is 1010
1010 ^ 1000 is 0010
0010 is 1101 ^ 1111正如Eric Postpischil所提到的:
函数的参数
n是long,但是代码只通过32位迭代i。它翻转n中的低32位,保留高位(如果有的话)不变。
如果long是32位,那么n = n ^ 1U << i就是实现--在某些情况下是定义的,因为带有unsigned int的long的^将导致unsigned long,如果结果值不能用long表示,则结果是实现定义的。
如果我们假设适当的n输入,例如在32位宽类型中可以表示,或者只有较低位的翻转是有意的,那么这就不是问题了。
请注意,加上Eric的注释,long是隐式签名的,这意味着准MSB不能完全用于值表示(无论是2-补码还是1-补码或符号表示),因为范围的一半用于负值。然后,通过异或切换它会产生潜在的奇怪效果。
发布于 2020-07-21 15:26:37
它将翻转n中较低的32位。这一总体效果将与只执行n ^= 0xFFFF相同。
在您的代码中,n是long。如果您使用的是32位编译器,那么它将有32位,但在其他编译器上可能会更长。
如果展开循环,就会得到如下内容:
n = n ^ 1U << 0;
n = n ^ 1U << 1;
n = n ^ 1U << 2;
...由于<<具有比^更高的优先级,这将解决以下问题:
n = n ^ 1;
n = n ^ 2;
n = n ^ 4;
...最终的效果是,它翻转32位的n,一次一位。
https://stackoverflow.com/questions/63017620
复制相似问题