float数据存储与转换:简单易懂

前言

float数据是如何存储的,很多时候我不必关心过多的细节,但是有时候又很重要,了解一些计算机的基础知识,也是趣味无穷。

float数据的存储结构

float占用4个字节Byte,一共32bit。
image.png
计算机中只有“0”和“1”,那么如何用0”和“1”表示浮点呢。
IEEE标准中,将32bit的内存分为3个部分。

  • 0~22bit,长度为23个bit,用M表示(Mantissa,小数部分)
  • 23~30bit,长度为8个bit,用E表示(Exponent,指数部分)
  • 31bit,最高位,只有1个bit,用S表示(Sign,符号)

那么浮点数的换算公式如下,就是科学计数法的表示方式。
D = S ∗ ( 1 + M ) ∗ 2 ( E − 127 ) D=S*(1+M)*2^{(E-127)} D=S(1+M)2(E127)-------(1)

  • S 很好理解,就是正号+或者符号-
  • E也很好理解,就是8个bit的二进制数对应的无符号整数,比如00000011b表示0x03=310100110b表示0xA6=166.
  • M理解稍难一些,因为涉及到二进制小数。假设在22bit的前面有一个小数点,那么需要把小数点后面的二进数转换为小数。比如 0.101 b = 1 ∗ 2 − 1 + 0 ∗ 2 − 2 + 1 ∗ 2 − 3 = 1 / 2 + 0 + 1 / 8 = 0.625 0.101b=1*2^{-1}+0*2^{-2}+1*2^{-3}=1/2+0+1/8=0.625 0.101b=121+022+123=1/2+0+1/8=0.625

二进制转float

可以计算S、E、M后,就可以计算对应的浮点数据。
直接举例说明吧,下图中,S = 0,E = 127, M = 0.625,带入公式(1)中:
D = ( + 1 ) ∗ ( 1 + 0.625 ) ∗ 2 ( 127 − 127 ) = 1.625 D=(+1)*(1+0.625)*2^{(127-127)}=1.625 D=(+1)(1+0.625)2(127127)=1.625
float数据存储与转换:简单易懂_第1张图片

再来一个例子,下图中,S=-1, E=129,E=0.625,带入公式(1)中:
D = ( − 1 ) ∗ ( 1 + 0.625 ) ∗ 2 ( 129 − 127 ) = 1.625 ∗ 4 = 6.5 D=(-1)*(1+0.625)*2^{(129-127)}=1.625*4=6.5 D=(1)(1+0.625)2(129127)=1.6254=6.5
float数据存储与转换:简单易懂_第2张图片

不管其它任何的数据,都可以按照上述方法计算,如果还不会,再看一遍。

float转二进制

float转二进制,就是上述计算逆运算,注意到公式(1)中M要加上1了吗?
对公式(1)进行变形,M写左边。因为 S = 1 / S S=1/S S=1/S,所以有
M = S ∗ D 2 ( E − 127 ) − 1 M=\frac{S*D}{2^{(E-127)}}-1 M=2(E127)SD1 --------(2)
这个公式中,除了符号位S外,仅仅只有D是已知的,如何求另外2个未知数呢?
这里要遵循2个原则

  • 先确定E,再确定M;
  • 确定E的方法是:让 D 2 ( E − 127 ) \frac{D}{2^{(E-127)}} 2(E127)D恰好是1.xxxx的形式,也就是这个数据的整数部分**必须是1,不能是0,也不能是2,或者其他。**E确定下来后,M也可以计算出来了。

还是举例说明,把13.25进行转换。

  • 首先13.25的整数部分不是1,需要进行换算,需要除8,也就是 2 3 = 2 E − 127 2^{3}=2^{E-127} 23=2E127,所以E=130=0x82
  • 13.25/8=1.65625=1+M,所以M=0.65625=0.10101b

所以有S=1,E=130,M=0.10101b,如下图所示。
float数据存储与转换:简单易懂_第3张图片

再来一个例子,把-0.20703125进行转换,S=-1。

  • 首先0.20703125的整数部分不是1,需要进行换算,需要乘8,也就是除1/8,也就是 2 − 3 = 2 E − 127 2^{-3}=2^{E-127} 23=2E127,所以E=124=0x7C
  • 0.20703125*8=1.65625=1+M,所以M=0.65625=0.10101b

所以有S=-1,E=124,M=0.10101b,如下图所示。
image.png

上述是关于float的介绍,double数据的转换就依葫芦画瓢吧,这里就不啰嗦了。

参考链接

float和二进制换算的计算器
https://www.h-schmidt.net/FloatConverter/IEEE754.html

扩展链接

FLT_EPFILION定义以及原理
https://frama-c.com/2013/05/09/Definition-of-FLT_EPSILON.html

你可能感兴趣的:(编程,算法,计算机原理)