事情是这样的,我想判断一个无符号64位整型数值的第7位bit(bit位从0开始计)是否为1,于是我写下了下面的代码来判断:

//... 省略其他环境代码 ...//
uint64_t bigint = 128;
bool 7_bit_is_one = (bigint & ((uint64_t)1 << 7) != 0);
// 7_bit_is_one = false

很奇怪对不对,128的第7位bit当然是1,当为什么结果7_bit_is_one为false呢?我开始也是百思不得其解,各位看官如果一眼看出原因所在,那下面不用看了,你比较牛~

其实(bigint & ((uint64_t)1 << 7) != 0); 这个表达式的运算顺序并不是预期的先算bigint & ((uint64_t)1 << 7) ,再判断其结果是否不等于0,而是先执行((uint64_t)1 << 7) != 0,再将其结果与bigint求位与运算。本质原因是在c++中 !=运算符的优先级大于&导致的,另外我在python中试了一下,结果如预期为true,所以python中优先级&大于或等于!=,因为&在前面,因此先运算位与运算。

因此在c++中要达到预期的执行运算顺序,因用小括号将bigint((uint64_t)1 << 7)括起来:

//... 省略其他环境代码 ...//
uint64_t bigint = 128;
bool 7_bit_is_one = ((bigint & ((uint64_t)1 << 7)) != 0);
// 7_bit_is_one = true

这个故事告诉我们,在写C++代码时要小心运算符的优先级,否则表达式实际执行的顺序可能并不是表达式的前后顺序,如果你不确定优先级,最好用小括号括起来,这样就不会有问题了。