IEEE 754 与浮点数的二进制表示ponder.work
本文同步发布个人博客
在计算机科学中,浮点(英语:floating point,缩写为FP)是一种对于实数的近似值数值表现法, 类似于十进制的科学计数法.
科学记数法
在科学记数法中,一个数被写成一个"实数"与一个10的n
次幂的积
其中: n
必须是一个整数, 可称之为指数。 a
必须是[1, 10)
区间内的实数,可称为有效数或尾数。
类似的,二进制的科学计数法则是
,不同的是
a
必须是
[1, 2)
区间内的实数。
所以浮点数的二进制表示,就是用二进制位表示为
。
IEEE 754浮点数表示
所以,我们可以将一定长度的二进制位分成三个部分,用来分别表示
、
、
,而IEEE 754就是具体实现的标准。
IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。
IEEE 754规定,对于32位的浮点数,最高的1位表示符号
记为
s
(sign),接着的8位表示指数
记为
E
(exponent),剩下的23位为有效数
记为
M
(fraction)。
8位二进制位,能表示的256个数值,由于指数有正有负,标准规定从-127开始计数,也就是-127到128(与有符号数的实现不同),而且-127和128被用作特殊值处理,见下方特殊值。
同时,由于M的整数部分永远是1,我们可以只表示其小数部分,记为N
。
也就是最终可表示为
。
具体各部分拆解如下,其中
到
对应32个二进制位的值,为
0
或者
1
。
以十进制的
为例,可表示为
。那么,s=1,N=0.25,E=2。
具体来说
特殊值
这里有三个特殊值需要指出: 如果指数是0并且尾数的小数部分是0,这个数±0(和符号位相关) 如果指数的二进制位全为1
并且尾数的小数部分是0,这个数是±∞(同样和符号位相关) * 如果指数的二进制位全为1
并且尾数的小数部分非0,这个数表示为非数(NaN)。
单精度浮点数各种极值情况:
浮点数与二进制字符串转换
def binary_to_float(data):
assert len(data) == 32
sign = (-1) ** int(data[0])
exponent = 2 ** (-127 + sum(int(a) * 2 ** b for a, b in zip(data[1:9], range(7, -1, -1))))
fraction = 1 + sum(int(a) * 2 ** b for a, b in zip(data[9:], range(-1, -24, -1)))
return sign * exponent * fraction
def float_to_binary(data):
import struct
bins = struct.pack('>f', data)
return ''.join('{:0>8}'.format(bin(i)[2:]) for i in bins)
参考
- https://zh.wikipedia.org/wiki/IEEE_754
- https://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html
- https://zh.wikipedia.org/wiki/%E7%A7%91%E5%AD%A6%E8%AE%B0%E6%95%B0%E6%B3%95
- 《深入理解计算机系统》