二进制
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(为了计算方便)。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。(百度百科)
原码、反码、补码
举例
原码 | 反码 | 补码 | |
---|---|---|---|
正数5 | 0000 0101 | 0000 0101 | 0000 0101 |
负数5 | 1000 0101 | 1111 1010 | 1111 1011 |
8位2进制数表示-128~127的范围,第一位表示符号位,1表示负数、0表示正数
正数三码都相同
负数:用绝对值的补码表示,负数=模-|负数|、-1=100-|-1|=100-001=011
- 原码=正数最高位改为1
- 反码=正数取反,第一位符号位不变
- 补码=反码+1,即取反+1,也可以用原码-1,再取反
- 模 = 原码+补码
想象成时钟,2点到4点,可以顺时针旋转2小时,也可以逆时针旋转10小时,即2=12-|-10|,12为模
想象成360度的圆,模代表一圈的度数:
- 起点为0度,范围是0~359。-1度=359度,-180度=180度,模=360度=1度+359度。
- 起点为-180度,范围是-180~179。那么:-181度=179度,模=360度=181度+179度。
位数越多、刻度越多:
- 如2位:能表示-2~1的数。1=01、-1=11、-2=2=10,模=100=01+11=10+10=进一位。进一位表示:2=010、-2=110,第一位表示符号位。
- 如3位:能表示-4~3的数。1=001、-1=111、-4=4=100,模为=001+111=100+100=1000=进一位。进一位表示:4=0100、-4=1100,第一位表示符号位。模为1000
- 如8位:能表示-128~127的数。1=00000001、-1=11111111、-128=128=10000000
- 可以总结出:n为位数,能表示-2^(n-1)=2^(n-1)
进制转换
二进制转十进制
例:二进制00001000
转换为十进制
(2^0)*0+(2^1)*0+(2^2)*0+(2^3)*1 = 8
十进制整数转二进制整数
除2取余,逆序排列:将循环除以2,直到商为0,记录每一步的余数,将每一步的余数倒序组成二进制
例:十进制5转换为二进制
1 | 5/2=2···1 |
十进制小数转换成二进制小数
乘2取整,顺序排列:整数部分同上,小数部分循环乘2,直到小数部分为0,记录每一步的积并取整数部分,顺序组成二进制小数部分
1 | (2.25)10转为二进制 |
同样的算法,小数部分可能永远不为0,如0.4
1 | 0.2*2=0.4 //整数部分为0 |
因子中包含5才能用2进制表示
位运算符
- &:位与and,将两个数转换为二进制,每一位进行比较,如果都为1则结果为1,否则为0
- |:位或or,将两个数转换为二进制,每一位进行比较,只要有一个为1则结果为1,否则为0
- ~:位非not,单目运算符,将每位取反,使用补码进行计算
- 如~37,8位机器上,补码为:00100101
- 取反:11011010=-38。
- 第一位是符号位,为1表示负数,负数的原码需要计算,对负数补码进行还原。(补码取反+1,或者补码-1取反)
- 补码减1得到反码:11011001
- 反码取反得正数(负数的反码为正数取反):00100110,即38
- 所以
37=(00100101)补码=11011010补码=-38
- ^:异或xor,将两个数转换为二进制,每一位进行比较,如果相同则为0,不相同则为1
左移(<<)、右移(>>)
左移n位相当于乘以2的n次方:把二进制的高位左移n位,溢出舍弃,右边空出来的补0
1 | 例:4<<2 = 4*2^2 = 16 |
右移n位相当于处以2的n次方:把二进制的低位右移n位,溢出舍弃,左边空出来的补0
1 | 例:4>>2 = 4/2^2 = 1 |
进制表示
进制 | 缩写 | C语言 | Java | 书写 |
---|---|---|---|---|
二进制 | B | 不能表示 | 不能表示 | 括号加下标:如(11)2,缩写后缀:11B,下同 |
八进制 | O | 0开头 | 0开头 | |
十进制 | D | |||
十六进制 | H | 0x或0X开头 | 0x开头 |
其他
位(bit)是计算机存储的最小单位,字节是计算机处理数据的最小单位,1字节=8位