关于~(按位取反)运算符
关于~(按位取反)运算符
众所周知, 各种语言均有一个运算符 " ~ ", 它表示将一个数按位取反
之前一直没有注意过这个运算符, 今天下午发现了一个小bug, 才算搞清楚了, 同时加深了对补码的理解, 这里记录一下.
首先让我们走进python
print(0b1001)
输出的结果为: 9
我就天真的以为0b表示的就是无符号数
但实际上
print(~0b1001)
输出的结果为: -10
原以为0b1001按位取反得到的结果为0b0110自然表示的就是6了, 可为什么会是-10这个东西呢
其实道理很简单, 比如我们用32位表示一个数, 那么0b1001写完整应该是:
0b00000000000000000000000000001001
那么按位取反, 其实表示的是32位全部取反
即:
0b11111111111111111111111111110110
由于最高位为符号位, 那么取反后的值用十进制表示为
0b11111111111111111111111111110110再按位取反+1后加上负号的值, 即: -10
由于python的整型不会溢出, 所以不管我们输入多少位都能表示成正的...比如
print(0b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001)
得到...
356811923176489970264571492362373784095686657
我们选择C语言来验证一波
首先,利用:
cout<< sizeof(int)*CHAR_BIT<<endl;
求得int的位数为32位, 那么按照想法, 我们直接将最高位置1, 得到的就应该是个负数,直接来个最大的:
int x = 0b10000000000000000000000000000000;
cout<<x<<endl;
输出为: -2147483648,
这也是int所能表示的最小值, 按照我们上面的分析, 最高位为1, 表示负数,那么各位取反得到:
0b01111111111111111111111111111111, +1 = 0b10000000000000000000000000000000
表示为十进制就是 $-2^{31} $ = -214783648
如果我们再取个反:
int x = 0b10000000000000000000000000000000;
cout<<~x<<endl;
得到的就是int的最大值: 2147483647 (0b01111111111111111111111111111111)了, 也就是 \(2^{31}-1\) 因为正数最高位只能为0, 所以不会有比这个更大的数了
总结就是, 我之前对按位取反的理解有误, 按位取反指的是全部位取反, 而不是用0bxxx表示出来的那几位
((逃