C++中的位运算和原码、反码、补码
在C、C++中有一系列位运算符,在学习位运算符的时候就需要先了解反码、补码的原理。 因为位运算是按照变量在内存中所表示来进行运算的。
而计算机中,数字是按照二进制的补码进行存储的,当然(其他类型以及高级类型本质上也是数字)
二进制的原码,就是将十进制数转换为二进制。
正数的 反码、补码和原码一致
负数的 反码、补码按照以下方式转换
反码:原码符号位不变,其他位按位取反就可以得到了。 补码:反码+1就得到补码。
int a = 251
int b = -232
a的原码:00000000 11111011
a的反码:00000000 11111011
a的补码:00000000 11111011
b的反码:11111111 00010111
b的原码:10000000 11101000
b的补码:11111111 00011000
a+b = 19
使用ab的原码相加 得 10000001 11100011
即 -483
使用ab的反码相加 得 00000000 00010010
即 18
使用ab的补码相加 得 00000000 00010011
即 19
使用补码,如果从比较粗浅的角度来理解,主要是因为负数存在一个 -0,这个 -0 和“正数”中的0 冲突了,在进行加法运算的时候,-0也占了一个位置,这样就会导致,正负数相加结果和我们数学体系中的表示结果差一位,所以负数一律补1,这样就规避掉-0这个陷阱了。
“这个问题理解的时候,我觉得不要讲计算机中的数字理解位数字,实际上计算机里没有所谓的正负,只是存在了2^n中状态,而我们人类数学刚好存在一个0点,这个0点在二进制表示中,其实不应该有位置,但是又必须有,所以就会导致另外一个对称状态很尴尬。”
回到位运算
<<
左移
int a = 5; a<<=1
0000 0101
->0000 1010
a=10
>>
右移
int a = 5; a>>=1;
0000 0101
->0000 0010
a=2
&
与(且)
int a = 5; a&=1;
0000 0101 & 0000 0001
> 0000 0001
a=1
int a = 5; a&=3;
0000 0101 & 0000 0011
> 0000 0001
a=1
|
或
int a = 5; a|=1;
0000 0101 | 0000 0001
> 0000 0101
a=5
int a = 5; a|=3;
0000 0101 | 0000 0011
> 0000 0111
a=7
^
异或 (不同)
int a = 5; a^=1;
0000 0101 ^ 0000 0001
> 0000 0100
a=4
int a = 5; a^=3;
0000 0101 ^ 0000 0011
> 0000 0110
a=6
~
取反 单目运算
int a = 5;
~0000 0101
> 1111 1010
(补码)
对补码进行还原 反码= 1111 1001
,得到原码 = 1000 0110
即
a= -6
文章地址: C++中的位运算和原码、反码、补码 - Sprite keep learning
最近回复