關於~(按位取反)運算符
眾所周知, 各種語言均有一個運算符 " ~ ", 它表示將一個數按位取反
之前一直沒有注意過這個運算符, 今天下午發現了一個小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表示出來的那幾位
((逃