计算机内存中float类型采用IEEE标准来表示。
IEEE关于浮点数的表示方式
IEEE关于浮点数表示是将浮点数二进制的若干位划分为一个符号位S、若干指数位E和若干尾数位M,任意V = S * (2 ** E) *M
形式如下:
+-+--------+-----------------------+
符号位为0,S = (-1) ** 0 = 1, 表示正数。符号位为1,S = (-1) ** 1 = 1,表示负数。
指数位的取值E与位数k有关,定义一个偏移量O = 2 ** (k -1) -1。 当k位全为0 即v(k) = 0时, E = 1 - O, 这时整个浮点数为“非标准化数“。当k位指数位取值不全为0或不全为1 即 0 < v(k) < 1时,E = v(k) - O,此时整个浮点数为”标准化数“。当k位指数位全为1时,此时整个浮点数为”特殊值“:当尾数为全为0时,这时表示的数为无穷大,根据符号位取值的不同,分为正无穷和负无穷; 当尾数位取非零值时,表示Nan,意味着非数。
m位尾数位的表示小数点后面的值,所以计算v(m)得到的值位于(0,1)之间。 M值的情况分为”标准化数“和”非标准化数“,当整个数为”标准化数“时M = 1 + v(m) , 当整个数为”非标准化数"时M = v(m)。根据指数位的不同, 尾数M的取值范围为(1, 2)或者(0, 1)。
IEEE关于浮点数表示的简单情况
先考虑简单的情况,我们自定义一个浮点类型采用IEEE标准表示为一个符号位、2个指数位和2个尾数位,这样就可以穷举所有可表示的浮点数,此时指数位的偏移量O=1。
符号位为0的所有情况:
符号位为1的所有情况
可以看到0.0分为+0.0和-0.0。
在给定位数的情况下,只能表示有限的浮点数,同时可表示的浮点数越靠近零点越密集。
针对非标准化数和标准化数采用不同的尾数M计算方式使得可表示的数集在非标准化数向标准化数跃进时更平滑。
float和double类型
float类型采用4个字节表示,在位的级别上就是将数据分为一个符号位、8个指数位和23个尾数位。
double类型采用8个字节表示,在位的级别上就是将数据分为一个符号位、11个指数位和52个尾数位。
float类型的浮点数可表示的最小非零正浮点数为0 0000 0000 0000 0000 0000 0000 0000 001,小数形式表示为1.401298464324817e-45。
float类型的浮点数可表示的最大非零正浮点数为0 1111 1110 1111 1111 1111 1111 1111 111,小数形式表示为3.402823466E+38。