定义
二进制数据是用0和1两个数码来表示的数,它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”
位数
二进制每个0或每个1就称做1位,1个字节是8位的数据单元,例:11001101 为一个字节;8位1字节
符号
无符号
不存在负数
8位二进制范围:0~255
- 11111111 :255
- 00000000 :0
有符号
正数:补全1个8位数据单元之后的最高位是0为整数
负数:补全1个8位数据单元之后的最高位是1为负数
算数运算,要取补码运算
8位二进制范围:-128~127
- 01111111 :127
- 10000000 :-128
- 10000001 :-127
- 11111111 :-1
运算
补高位运算
无符号
高位补0
有符号
单位字节内
- 不满1个字节,补全一个字节
- 高位补0
- 例子:10110 -> 00010110
单位字节外
- 补全字节数,比如1个字节要扩展到4个字节。另外3个字节补全
- 高位补的值与符号匹配;
- 符号位为0,高位全补0;
- 符号位为1,高位全补1
- 例子:
- 10110 -> 00010110 ->00000000 00000000 00000000 00010110
- 11011010 -> 11111111 11111111 11111111 11011010
原则:补高位不能改变数的值
符号位为0的补0计算结果不变
符号位为1的补1取补码,1变为0,这样计算结果也不变
有符号的二进制运算
原码
样例:11010111
原码:不能直接参与运算
- 00001011 -> 11 ;10001011 -> -11 ;11 + (-11) = 0
- 00001011 + 10001011 = 10010110 -> -22
- 运算是有问题的
反码
正数的反码 = 原码;01010111 -> 01010111
负数的反码:原码的每位取反,符号位保持不变;11010111 -> 10101000
补码
正数的补码 = 原码;01010111 -> 01010111
负数补码:符号位不变,其他位取反+1;也就是反码之后+1;11010111 -> 10101001
参与算数运算的都是补码
00001011 -> 11 ;10001011 -> -11 ;11 + (-11) = 0
00001011(正数补码就是原码) + 11110101(补码) = 00000000 (高位1溢出)-> 0
运算没有问题
原则:有符号二进制,高位为1的先进行补码之后才能参与运算
四则运算
加
逢2进1:0+0=0;0+1=1;1+0=1;1+1=10
减
向高位借1当2:1-1=0;1-0=1;0-0=0;0-1=1
乘
只有同时为“1”时结果才为“1”:0×0=0;0×1=0;1×0=0;1×1=1
除
二进制数只有两个数(0,1),因此它的商是1或0:0÷1=0;1÷1=1
位运算
位运算是二进制本质的运算,非数值运算,用给定的二进制直接运算就行,不需要转补码
& :按位与
同位运算;高位补全,两个数位数相同
整数部分从低位开始对应到高位,小数部分从高位对应到低位
相同位的两个数字都为1,则为1;若有一个不为1,则为0
例子:101010 & 11110110 = 00100010
“ | ” :按位或
同位运算
相同位只要一个为1即为1
例子:101010 | 11110110 = 11111110
“ ^ ” :按位异或
同位运算
相同位数值不同则该位为1, 相同该位为0 (相同为0、相异为1)
例子:101010 | 11110110 = 11011100
“ - ” :按位取反
同位取反,1则为0, 0则为1
例子:-101010 = 010101
“ << ” :左移
往左边移动几位,右边就补几个0
正因为是右边补0,右边如果有1移到符号位,结果就产生负数
例子
- 00000111 << 2 = 00011100
- 7 << 2 = 28 (同上)
- 7 * 4 = 28,左移几位,就是把原来的数 * 2的位移次指数;但要考虑符号位
左移一位,相当于乘2
“ >> ” :右移
往右边移动几位,左边补符号位
即正数则左边补0,负数则左边补1
例子
- 00000111 >> 2 = 00000001
- 10000111 >> 2 = 11100001
右移一位,相当于除2,舍弃小数取整
“ >>> ” :不带符号右移
右移左边全补0,不管是正数还是负数
例子
- 00000111 >> 2 = 00000001
- 10000111 >> 2 = 00100001