整数编码
原码
将数字的最高位视为符号位,0为正,1为负,其余为表示数字的值
比如 1个字节(byte)是8个比特(bit),一个比特代表一个二进制位
+0 的原码是 0000 0000
+5 的原码是 0000 0101
-0 的原码是 1000 0000
-28 的原码是 1001 1100
反码
正数的反码和原码一样; 负数的反码是对原码除了符号位外取反
+0 的反码是 0000 0000
+5 的反码是 0000 0101
-0 的反码是 1111 1111
-28 的反码是 1110 0011
补码
正数的补码和原码一样; 负数的补码是在反码的基础上+1
+0 的补码是 0000 0000
+5 的补码是 0000 0101
-0 的补码是 0000 0000
-28 的补码是 1110 0100
计算机运算使用补码,因为补码可以直接用于运算(如果用原码1+(-2)是错的)且没有正负0歧义(补码的正负0都是0000 0000)。
需要注意的是,补码1000 0000没有对应的原码,根据转换方法,1000 0000的原码应该是0000 0000,明显不对,所以计算机规定补码1000 0000表示-128。所以byte类型(1字节)的取值范围是[-128, 127]
浮点数编码
float(4字节)类型的取值范围之所以比int(4字节)类型大,就是因为浮点数有自己的编码方式。
一个4字节(32bit)的二进制数为
根据IEEE 754标准,32bit长度的float由以下三个部分构成:
- 符号位S: 占1位,对应b31
- 指数位E:占8位,对应b30-b23
- 分数位N: 占23位,对应b22-b0
二进制float计算方式为
转换成十进制就是
比如:
各项的取值范围是
E为0或者255的时候有特殊意义,表示0、无穷大、NaN等
因为float的表示方式包含指数位,导致其取值范围远大于int,根据以上计算公式,float可表示的最大正数为
切换符号位就可以得到最小负数。
虽然float扩大了取值范围,但是代价是降低了精度,整数int类型将全部32bit用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数float的数值越大,相邻两个数字之间的差值就会越大。
次正规数显著提升了浮点数的精度,最小正正规数为
;最小正次正规数为
。
双精度double和float的表示方法类似。