计算机浮点数那些事

独奏

学习思考|2017-3-12|最后更新: 2023-2-23|
type
status
date
slug
summary
tags
category
icon
password

十进制小数转二进制小数

对十进制小数乘2得到的整数部分和小数部分,整数部分既是相应的二进制数码; 再用2乘小数部分(之前乘后得到新的小数部分),又得到整数和小数部分; 如此不断重复,直到小数部分为0或达到精度要求为止。 第一次所得到为最高位,最后一次得到为最低位。
如:
0.8125的二进制:
0.81252=1.625 取整是1 0.6252=1.25 取整是1 0.252=0.5 取整是0 0.52=1.0 取整是1
即0.8125的二进制是0.1101(第一次所得到为最高位,最后一次得到为最低位)
0.1 的二进制:
乘数
乘2结果
整数部分
说明
0.1
0.2
0
0.2
0.4
0
0.4
0.8
0
0.8
1.6
1
减1
0.6
1.2
1
减1
0.2
0.4
0
0.4
0.8
0
0.8
1.6
1
减1
0.6
1.2
1
减1
可见,十进制 0.1 转为二进制后为 0.000110011001100110011... 无限循环小数

计算机浮点数表示

计算机存储浮点数遵循 IEEE 754 格式。
V = (-1)^S * M * 2^E
  • S(Sign/1bit):符号部分,当 S=0,V 为正数;当 S=1,V 为负数。
  • E(Exponent/8bits):指数部分。以2为底。需要注意的是,E 在这里是一个无符号整数,但是实际上指数是可以存在负数的,所以 IEEE 754 规定,E 需要偏移127(64位为1023),如,2^10 的指数是10,保存成32位浮点数时,必须保存成 10+127=137,即10001001。
  • M(Mantissa/23bits):表示有效数字,大于等于1,小于2。第一位 1 可以被舍去,只保留小数部分节省一位有效数字。
指数 E 还分为三种情况:
  1. E 不全为0或不全为1。这时,浮点数就采用上面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
  1. E全为0。这时,浮点数的指数E等于 1-127(或者 1-1023),有效数字M不再加上第一位的1,而是还原为 0.xxxxxx 的小数。这样做是为了表示±0,以及接近于0的很小的数字。
  1. E全为1。这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);如果有效数字M不全为0,表示这个数不是一个数(NaN)。
IEEE 754 中规定:
对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M; 对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
notion image

计算误差

下面以双精度 double 类型的 0.1+0.2 为例
可以发现,由于十进制下的部分小数无法使用二进制精确表示,所以会存在一定的计算误差。在平常应用中我们很少会遇到这个问题,比如遇到支付宝这样的货币系统,需要高精度的计算时,通常我们会定义精确到小数点后两位,然后使用整形来代替浮点型,即使用一分钱的整数倍。