为什么 2**-1025 != 0.0 在 Python

Why does 2**-1025 != 0.0 in Python

根据IEEE754的规范,64位编码的浮点数有11位指数和52位尾数。因此,可以编码为浮点数的较小数字应该是 2**(-2**10)wikipedia page 我相信是真的,给出更精确的 2**-1022 的值,其十进制值大约是 2.2250738585072014e-308.

但是,对于 Python,我可以使用 2**-1052 等浮点数。我的计算机上的实际限制是 2**-1074。由此page of the official documentation,Python通常符合IEEE754.

同时,最大值为2**1023,这是IEEE754标准给定的值

binary64 使用有偏指数和 53 位尾数对大多数值进行编码。

偏置指数为1或更多**,值为:1.the_52_bit_encoded_"mantissa" * 2指数-偏差.

偏置指数为0,值为:0.the_52_bit_encoded_"mantissa" * 21 - bias.

OP 是 正常 值的正确想法。但是存在 次正常 值,它们在 0.the_52_bit_encoded_"mantissa" 中有不同数量的前导零。最小的非零则为 0.(51_zeros)1 * 21 - bias 或 2-1074.


** 当偏置指数有最大值时,数字是特殊的:要么是 infinity 要么是 非数字.

首先,Python 文档没有指定使用 IEEE-754。浮点实现的选择取决于每个 Python 实现。 IEEE-754 很流行但不通用。

在IEEE-754基本64位二进制浮点格式(binary64)中,有一个一位的符号域s,一个 11 位指数字段 e,和一个 52 位主要有效数字字段 f(对于“分数”)。

符号位为0表示正,1表示负。

如果e全为1(1111111111,十进制为2047),对象表示无穷大(如果f为零) 或 NaN(如果 f 不为零)。 (“NaN”代表“不是数字”)。

如果e既不是全零位也不是全1位,那么它代表一个指数E = e − 1023,并且 f 字段用于构成数字 F 即 1.f(即二进制数“1.”后跟 f 的 52 位)。 (等价地,如果我们把 f 看成一个二进制数,我们可以说 F = 1 + f • 2−52.) 表示的数为(−1)s • 2EF。这些被称为正常数字。

e全为零位,则表示指数E = 1 − 1023, f字段用于组成一个数F即0.f(即二进制数“0”。然后是 f 的 52 位)。 (等价地,我们可以说 F = 0 + f • 2−52。)表示的数字是 (−1)s • 2EF。这些被称为次正规数。

注意e = 1和e = 0表示相同的指数E, 1 − 1023 = −1022,但将 F 的第一位从 1 更改为 0。 F 是有效数字(小数部分)浮点数。 (人们有时将 f 称为有效数 1,但这是不正确的。它只是提供大部分数学编码的字段尾数。正如我们在上面看到的,指数字段也有助于形成实际的尾数,F。)

最小正数出现在s为零,e为零,f 是 1 (0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001)。则 E = −1022 且 F = 0 + 1 • 2−52, 所以表示的数是 (−1)0 • 2−1022 • 2−52 = 2−1074.

最大有限数出现在s为零,e为2046(11111111110),f 是所有的 (1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111)。 E = 2046 − 1023 = 1023。请注意 f,解释为整数时,是 252 −1,所以 F = 1 + *(252−1) • 2−52 = 1 + 1 − 2−52 = 2 - 2−52。所以表示的值是 (−1)0 • 21023 • (2 - 2−52 ) = 21024 − 2971.

脚注

1 有效数有时被称为“尾数”,但这是对数的小数部分的旧术语。它并不完全适合浮点数,因为尾数是对数的,而尾数是线性的。