浮点的字节表示为整数方程

时间:2018-01-12 17:39:24

标签: math floating-point interpretation

this文章中使用的方程我不明白:

  • I =(e + B)* L + m * L

I 是解释为整数的float的字节表示。 这是一个例子:

struct.unpack('8sii', f.read(16))
  • e 是浮点数的指数。
  • B 是偏见(127)。
  • L 是常数(1 <&lt; 23)。
  • m 是尾数。

现在我的问题是:

为什么方程式是正确的,哪里可以阅读更多有关此等式的内容?

2 个答案:

答案 0 :(得分:1)

浮点编码

浮点数用符号 s ,指数 e 和有效数 f 表示。 (有些人使用术语“尾数”,但这是对数纸表的遗留物。对于浮点值的小数部分,“有意义”是优选的.Mantissas是对数的。有效数是线性的。)在二进制浮点数,表示的值为+ 2 e f 或 - 2 e < / sup>• f ,根据符号 s

通常对于二进制浮点,有效数必须在[1,2]中,至少对于格式的正常范围中的数字。对于编码,第一位与其余位分开,因此我们可以写 f = 1 + r ,其中0≤ r &lt; 1。

在IEEE 754基本二进制格式中,浮点数被编码为符号位,一些指数位和有效位字段:

  • 符号 s 编码为0位为正,1为负。由于我们采用对数,因此数字可能是正数,我们可能会忽略符号位以用于当前目的。

  • 指数位是实际指数加上一些偏差 B 。 (对于32位格式, B 为127.对于64位,为1023。)

  • signifcand字段包含 r 的位。由于 r 是一个分数,因此有效数字段包含以“二进制点”之后的二进制表示的 r 位。例如,如果 r 是5/16,二进制是“.0101000 ...”,因此有效数字段包含0101000 ...(对于32位格式,有效数字字段包含23位。对于64位,52位。)

b 有效数字段(23或52)中的位数。设 L 为2 b

然后 r L r L 的乘积是一个等于内容的整数有效数字域。在我们的示例中, r 是5/16, L 是2 23 = 8,388,608, r L = 2,621,440。因此有效数包含2,621,440,即0x280000。

等式 I =( e + B )• L + m L 尝试捕获此内容。首先,符号被忽略,因为它是零。然后 e + B 是指数加偏差。乘以 L 将其移位 b 位,将其置于浮点编码的指数字段的位置。然后添加 r L 添加有效数字段的值(我将 r 用于“其余有效数字”而不是 m 表示“尾数”)。

因此,当将2 e •(1+ r )编码为浮点数时,将其解释为二进制整数,( e + B )• L + r L

更多信息

有关IEEE 754的信息位于Wikipediathe IEEE 754 standard。以前的一些Stack Overflow答案描述了herehere的编码格式。

别名/重新解释位

关于你问题中的代码:

float x = 3.5f;
unsigned int i = *((unsigned int *)&x);

不要使用此代码,因为它的行为不是由C或C ++标准定义的。

在C中,使用:

#include <string.h>
...
unsigned int i; memcpy(&i, &x, sizeof i);

或:

unsigned int i = (union { float f; unsigned u; }) { x } .u;

在C ++中,使用:

#include <cstring>
...
unsigned int i; std::memcpy(&i, &x, sizeof i);

这些方法被定义为将浮点编码的位重新解释为unsigned int。 (当然,它们要求在您使用的C或C ++实现中floatunsigned int的大小相同。)

答案 1 :(得分:0)

如您所知,浮点数存储在IEEE 754标准中。和单精度浮点的位模式如下(见详情here):

enter image description here

根据以下公式计算数字的值:

enter image description here

因此,对于32位值,等效整数将为e * L + m。 因为指数是从(第23位)开始,第一部分是m。 假设指数与-127一起存储,表达式将转换为(e + B)*L + m

关于L之后的m可能会有一个假设,可能在文章中没有提及。

此外,此公式中未考虑sign位。