奇怪的按位异或行为

时间:2012-07-03 19:24:14

标签: bit-manipulation

为什么以下“交换”操作会在随机时间失败?

int i,p,a[11] = {0,1,2,3,4,5,6,7,8,9,10 };

srand(time(0));

for (i=0;i<11;i++)
{
    p = rand() % 11;
    a[i] = a[i] ^ a[p];
    a[p] = a[i] ^ a[p];
    a[i] = a[i] ^ a[p];
}

this answer中的逻辑没有什么不同 它将适用于3/4运行,然后开始复制0

在C和C ++中尝试过相同的结果

[编辑]
通过初始化p=0并使用while (p==i) p = rand() % 11;

替换相关行来解决此问题

更新: reason NOT to use xor(请参阅Mark Byers' answer和评论)

5 个答案:

答案 0 :(得分:6)

如果p恰好与i相同,则a[i] ^ a[p]将为零,其余功能将失败。

从统计数据来看,您的代码实际上有65%的机会以这种方式失败。

确保在生成p时,它与i的数字不同。例如:

p = rand() % 10;
if( p >= i) p++;

答案 1 :(得分:5)

i等于p时,a[i] ^ a[p]变为零。你的“交换”操作被打破了。

要交换,您应该使用临时变量:

int temp = a[i];
a[i] = a[p];
a[p] = temp;

不要使用XOR黑客。

答案 2 :(得分:1)

因为p随机等于i。在这种情况下,a[i]立即变为0。

答案 3 :(得分:1)

如果i == p,则a[i]会存储0

答案 4 :(得分:1)

作为开发实践,不建议进行XOR交换。但是如果你使用逻辑来获得乐趣,那么使用这一行将确保p与i不相同。

p = ((rand()%10)+(i+1))%11;

p = ((rand()%(count-1))+(i+1))%count;

但请注意,这个技巧对于性能视角并不好,因为它需要两个模块运算符和一个加法(或减法)。使用精确比较(这是最快的比较运算符),如果它们相同则加1。

p = rand()%10;
if (p == i) p++;