关于~(按位取反)运算符

关于~(按位取反)运算符

众所周知, 各种语言均有一个运算符 " ~ ", 它表示将一个数按位取反

之前一直没有注意过这个运算符, 今天下午发现了一个小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表示出来的那几位

((逃

posted @ 2020-06-02 19:16  roccoshi  阅读(2206)  评论(0编辑  收藏  举报