Why doesn't this work?


#1

I have 2 solutions, 1 working and 1 not. They look to me as if they should behave identically so I’m not sure what’s happened:

Working:

uint64_t interimNum = 1, finalNum = 0;

for (int i=0; i<64; i+=2) {
    finalNum = finalNum | (interimNum << i);
}

printf("%lld\n", finalNum);

Not Working:

uint64_t interimNum, finalNum = 0;

for (int i=0; i<64; i+=2) {
    interimNum = 1 << i;
    finalNum = finalNum | (interimNum);
}

printf("%lld\n", finalNum);

Strangely, the second solutions gives a result of 1,229,782,938,247,303,441. I’ve done some monitoring of what interimNum is actually doing and it appears that for i = 33, interimNum = 1… for i = 35, interimNum = 4. In other words, interimNum is behaving as a 32 bit integer and re-setting itself. Why is this occurring? Both solutions look to me as if they should behave identically.


#2

Logic is correct, but implementation is not.

Typecast that [color=#FF0000]1[/color] to promote it to uint64_t:

int main (int argc, const char * argv[])
{
    uint64_t interimNum = 1, finalNum = 0;
    
    for (int i = 0; i < 64; i += 2) {
        finalNum = finalNum | (interimNum << i);
    }
    
    printf ("%lld\n", finalNum);
    {
        uint64_t interimNum, finalNum = 0;
        
        for (int i = 0; i < 64; i += 2) {
            interimNum = ((uint64_t)1) << i;
            finalNum = finalNum | (interimNum);
        }
        
        printf ("%lld\n", finalNum);
    }

    return 0;
}

To get:

6148914691236517205
6148914691236517205