在计算机内,有符号数有3种表示法: 原码,反码,和补码.所有数据的运算都是采用补码进行的.
原码 就是二进制定点表示法,即最高位为符号位,”0”表示正,”1”表示负,其位表示数值的大小.
反码 正数的反码与其原码相同,负数的反码是对其原码逐位取反,但符号位除外.
补码 正数的补码与其原码相同,负数的补码是在其反码的末位加1.
更好的理解,用原码,反码,补码来分别表示+6和-6
原码 正数的原码最高位是 0,负数的原码最高位是 1 ,
其位表示数值的大小.
符号位 数值位
+6 0 0000110
- 6 1 0000110
反码 正数的反码与原码相同'
负数的反码与原码符号位相同,数值位取反(就是1变0,0变1).
符号位 数值位
+6 0 0000110
- 6 1 1111001
补码 正数的反码与原码相同.
负数的补码是在反码的基础上加1.
符号位 数值位
+6 0 0000110
- 6 1 1111010
位运算符 & , | , ^ , ~
int a = 6; int b = 3; 求 a&b ,a|b , a^b , ~6;
6的二进制: 110
原码: 00000000 00000000 00000000 00000110
3的二进制: 11
原码: 00000000 00000000 00000000 00000011
用6和3的补码运算得到: &: 位与运算 (有0则0)
6&3: 00000000 00000000 00000000 00000010 //2
| : 位或运算(有1则1)
6|3 : 00000000 00000000 00000000 00000111 //7
^ : 位异或运算(相同则0,不同则1)
6^3: 00000000 00000000 00000000 00000101 //5
~:按位取反运算符(0变1,1变0)
~6 : 11111111 11111111 11111111 11111001 (补码)
11111111 11111111 11111111 11111000 (反码)
00000000 00000000 00000000 00000111 (原码) //-7
位移运算符 << 左移 ,左边最高位丢弃,右边补齐0,
>> 右移,最高位是0,左边补齐0;最高位是1,左边补齐1
>>>无符号右移,无论最高位是0还是1,左边补齐0
int i = 6; int k =8; 求 i<<1 ,i>>1 , k<<2 , k>>2 ;
6的二进制: 110
原码: 00000000 00000000 00000000 00000110
8的二进制: 1000
原码: 00000000 00000000 00000000 00001000
<<左移: 把<<左边的数据乘以2的移动次幂
6<<1: (0)0000000 00000000 00000000 000001100 //12
8<<2: (00)000000 00000000 00000000 0000100000 //32
>>右移: 把>>左边的数据除以2的移动次幂
6>>1: 000000000 00000000 00000000 0000011(0) //3
8>>2: 0000000000 00000000 00000000 000010(00) //2
int i = 24; int k = -24; 求 i >>2, k>>2, i>>>2, k>>>2;
24的二进制: 11000
原码: 00000000 00000000 00000000 00011000
-24的原.反.补码
原码: 10000000 00000000 00000000 00011000
反码: 11111111 11111111 11111111 11100111
补码: 11111111 11111111 11111111 11101000
24>>2 = 6
-24>>2 : 11111111 11111111 11111111 111010(00) (补码)
11111111 11111111 11111111 111001 (反码)
10000000 00000000 00000000 000110 (原码) // -6