简体   繁体   中英

Shifting with uint64_t not working as expected

For part of a larger task, I was asked to implement a function that flips an arbitrary bit in an integer. The catch is that the "integer" could be any of the default integer types in c, from int8_t to uint64_t, and I don't know which one it will be. (In fact, my code has been tested on all of these types)

This was my attempt at the problem:

//NOTE: g_int is the generic integer, it's typedef'd in a .h file
g_int flip_bit(g_int b, uint8_t i){
    //Code that makes sure i is a valid amount to shift by, there's a macro
    //that defines the upper bound of i in a .h file.
    g_int flipped = b ^ (1<<i);
    return flipped;
}

This code xors the i th bit in b with 1, and the other bits in b with 0. This should flip the i th bit while leaving the rest unchanged. Satisfied with this, I tested my code on all of these different integer sizes, and then turned it in. However, I must not have tested enough, as my code failed on both int64_t and uint64_t.

What did I do wrong for int64_t and uint64_t, and is there something I can do to make my method work without changing it entirely?

This problem is caused by the type of 1, which is int (which has 32 bits on a reasonable machine). This means that performing the shift (1<<i) for values of i greater than or equal to 32 will result in undefined behavior.

This can be fixed simply by casting 1 to type g_int before performing the shift:

g_int flip_bit(g_int b, uint8_t i){
    g_int flipped = b ^ (((g_int)1)<<i);
    return flipped;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM