【问题标题】:What is n= n ^1U<<i?什么是 n=n ^1U<<i?
【发布时间】:2026-01-13 19:10:02
【问题描述】:

我在这里面临的问题是要了解循环的每次迭代中n 的值的变化。
如果您通过 2-3 次迭代来解释它,那就太棒了。 更正 - 返回值应该是 32 位 ....这正在改变所有位 0->1 和 1->0 。

long fun(long n)
{
    for(int i = 0; i < 32; i++)
        n = n ^ 1U << i;
    return n;
}   

【问题讨论】:

标签: c++ c loops iteration bit-manipulation


【解决方案1】:

i 正在计数。
1U &lt;&lt; i 是单个无符号位 (LSB),它每转左移 i,即扫描位位置,0001、0010、0100 , 1000(请读为二进制)。
n = n ^ 1U &lt;&lt; in 设置为n 的XOR 和移位的位。 IE。它会一点一点地异或 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 提到的:

该函数的参数nlong,但代码仅通过32 位迭代i。它会翻转n 中的低 32 位,而保留高位(如果有)不变。
如果long 是32 位,那么n = n ^ 1U &lt;&lt; i 在某些情况下是实现定义的,因为long^unsigned int 将导致unsigned long,并且如果结果值不能以long 表示,结果是实现定义的。

如果我们假设 n 的合适输入,例如可以在 32 位宽类型中表示,或者仅翻转低位是有意的,那么这不是问题。
请注意这一点和 Eric 的评论,long 是隐式签名的,这意味着准 MSB 不能完全用于值表示(无论是 2 补码还是 1 补码或符号表示),因为范围的一半是用于负值。通过 XOR 切换它可能会产生奇怪的效果。

【讨论】:

    【解决方案2】:

    它将翻转n 中的低32 位。总效果与n ^= 0xFFFF 相同。

    在您的代码中,nlong。如果您使用的是 32 位编译器,那么它将有 32 位,但在其他编译器上可能更长。

    如果你展开循环,你会得到这样的结果:

    n = n ^ 1U << 0;
    n = n ^ 1U << 1;
    n = n ^ 1U << 2;
    ...
    

    由于&lt;&lt; 的优先级高于^,这将解决这个问题:

    n = n ^ 1;
    n = n ^ 2;
    n = n ^ 4;
    ...
    

    最终效果是它翻转 32 位 n,一次一位。

    【讨论】:

    • 函数的参数nlong,但代码仅通过32 位迭代i。它会翻转n 中的低 32 位,而保留高位(如果有)不变。
    • 如果long是32位,那么n = n ^ 1U &lt;&lt; i在某些情况下是实现定义的,因为long^unsigned int会导致unsigned long,并且,如果结果值不能在 long 中表示,则结果是实现定义的。