适用于uint64和uint32的循环不适用于uint8或uint16

时间:2013-10-21 13:35:55

标签: objective-c bit-manipulation uint32

我想出了一个使用按位运算的循环,产生一个数字,其他所有位都打开(即8位,01010101)。

理论上,我的循环应该可以正常工作,它可以与uint32uint64一起使用,但不能uint8uint16。我想知道为什么......

以下是代码:

@autoreleasepool {
    // a = 00000000
    uint32 a = 0;
    // b = 11111111
    uint32 b = ~a;
    // a = 11111111
    a = ~a;

    // if (a = 01010101) ~a = 10101010, a << 1 = 10101010
    while (~a != (a << 1)) {
        // 1st time: a << 1 = 11111110 = a
        // 2nd time: a << 1 = 11111010 = a
        a = a << 1;
        // 1st time: ~a = 00000001 = a
        // 2nd time: ~a = 00000101 = a
        a = ~a;
        // 1st time: a << 1 = 00000010 = a
        // 2nd time: a << 1 = 00001010 = a
        a = a << 1;
        // 1st time: b ^ a = 11111101 = a
        // 2nd time: b ^ a = 11110101 = a
        a = b ^ a;
    }

    NSLog(@"%x", a);
    NSLog(@"%u", b);



    // Apply the same loop to a bigger scale
    uint64 x = 0x0;
    uint64 y = ~x;
    x = ~x;

    while (~x != (x << 1)) {
        x = x << 1;
        x = ~x;
        x = x << 1;
        x = y ^ x;
    }

    NSLog(@"%llx", x);
    NSLog(@"%llu", x);
}
return 0;

1 个答案:

答案 0 :(得分:1)

“小于int” starblue表示sizeof(a) < sizeof(int)。由于integer promotion rule,在执行操作之前,始终提升为int的类型比int更窄。有关详细信息,请参阅Implicit type promotion rules

因此,如果a为uint8uint16,则 ~a的高位始终为1 且永远不会等于{{ 1}}

例如,如果a是a << 1,运行几次迭代我们得到= 0x5555。在那之后

uint16

如您所见,(int)a = 0x00005555 ~a = 0xFFFFAAAA a << 1 = 0x0000AAAA 和程序将永远循环