Цикл, который работает для uint64 и uint32, не работает для uint8 или uint16

Я придумал цикл с использованием побитовой операции, в результате чего число, в котором включен каждый второй бит (т. Е. В случае 8-бит, 01010101).

Теоретически, мой цикл должен работать очень хорошо, и он отлично работает с uint32 а также uint64, но нет uint8 или же uint16, Интересно, почему...

Вот код:

@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 ответ

"Меньше чем int" означает синий sizeof(a) < sizeof(int), Из-за правила целочисленного продвижения типы, меньшие, чем int, всегда переводятся в int перед выполнением операций. Следовательно, если а uint8 или же uint16верхние биты ~a всегда будет 1 и никогда не может быть равен a << 1

Например, если это uint16, выполнив несколько итераций, мы имеем = 0x5555. После этого

(int)a = 0x00005555
    ~a = 0xFFFFAAAA
a << 1 = 0x0000AAAA
=> ~a != (a << 1)

и программа зациклится навсегда

Другие вопросы по тегам