使用uint64_t进行移位无法按预期工作

Unk*_*ble 2 c bit-manipulation c99

对于更大任务的一部分,我被要求实现一个翻转整数中任意位的函数.问题是"整数"可以是c中的任何默认整数类型,从int8_t到uint64_t,我不知道它将是哪一个.(事实上​​,我的代码已经在所有这些类型上进行了测试)

这是我对这个问题的尝试:

//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;
}
Run Code Online (Sandbox Code Playgroud)

此代码异或的i在第i比特b与1,而在其他位b为0.这应当翻转i个比特,同时留下其余部分保持不变.对此感到满意,我在所有这些不同的整数大小上测试了我的代码,然后将其打开.但是,我必须测试不够,因为我的代码在int64_t和uint64_t都失败了.

我对int64_t和uint64_t做了什么错误,我能做些什么来让我的方法工作而不完全改变它?

Unk*_*ble 5

这个问题是由类型1引起的,它是int(在合理的机器上有32位).这意味着(1<<i)对i的值大于或等于32 执行移位将导致未定义的行为.

这可以通过g_int在执行班次之前将1转换为类型来解决:

g_int flip_bit(g_int b, uint8_t i){
    g_int flipped = b ^ (((g_int)1)<<i);
    return flipped;
}
Run Code Online (Sandbox Code Playgroud)

  • 唯一的修正是超出整数宽度的是*未定义的行为*(不为零).http://port70.net/~nsz/c/c11/n1570.html#6.5.7p4 (3认同)