连续浮点数之间的差距

Gaps between successive floating point numbers

(讨论的所有数字均为十进制)

假设我们有一个浮点数据类型,类似于:

m * 10 ^ e

where m is the mantissa . and max mantissa size is 1 ( 0 <= m <= 9);

e is the exponent and its size is  -1 <= e <= 1

我们说我们的数据类型Max值为90,Min值为0

但是:这并不意味着我们可以表示此限制内的所有数字。 我们只能表示 27 个数字 ( 9 * 3 ),不包括零。

具体来说,我们不能用这种方式表示 89,因为它有两位数的尾数 (并且它们都不是零)。

在技术上与上述描述类似。在浮点数据类型中(在任何编程语言中)必须有一些我们不能存储在浮点数据类型中的最大值和最小值之间的整数。

就是上面的论证。如果是,请举例说明如何在 java 或 c 中显示它?

是的,你的推理是正确的,应该很容易找到你的数据类型无法表示的实数。

考虑您允许的最小尾数 (0) 和指数 (-1):

0 * 10 ^ -1

= 0.0

您允许的下一个更高的尾数是 1:

1 * 10 ^ -1

= 0.1

不能表示0.0到0.1之间的任何实数,比如0.05。

你应该可以用 Java 或 C 来表达。

你的推理是完全正确的。最简单的展示方式就是像你所做的那样。

一个non-representable例子

考虑 "usual single floating point" 格式,由 IEEE-754 定义,它有 7 个指数位,因此范围超出 [-2^127,2^127]

它也有24个尾数位,我们考虑一下 67108864、67108865和67108866。这些数字分别是2^26、2^26+1和2^26+2。

尝试将它们规范化以将它们写入浮点格式,您会看到

  • 尾数得到值26
  • 第一位消失了,因为在 IEEE-754 格式中隐含第一个数字总是* 1,所以每个数字剩下 25 位
  • 接下来的所有位(以 24 位为限)组成尾数...
    • 67108864 在它的尾数中只有零,因为它的最小位是 0 你可以删除它而不会丢失信息。
    • 67108866 在其尾数的最后位置有一个 1,因为它的最小位也是 0 你仍然可以删除它而不会丢失信息。
    • 67108865只有0和1作为最小位,超出了24位!因此,该数字将四舍五入为 2^26 或 2^26+2。

因此你有一个例子,比如 89 : 67108865 不能用浮点数表示。


* 除了次正规,见下文(扩展评论)

偏差

确实我在这里跳过了一部分。指数没有直接编码在保留给它的位中,它是 biased。在单浮点数的情况下,偏差为127.

所以我们的 26 实际上是由 26+127 表示的,因此是 153。从维基百科盗用以下图片:

如果你把这些数字(符号、指数和尾数)按照它们写的那样来表示,并想表达一个 non-subnormal 数字,你会得到:(-1)符号 * 2(exponent-127) * 1.mantissa

次正规

一旦我们达到可能的最小指数,即一旦我们将其写为 0 并表示 -127,我们就不再假设初始值 1。这样,我们可以表示小于 2-127 的数字(通过牺牲精度,因为我们将在尾数上有前导 0)。

然后我们有:(-1)sign * 2-127 * 0.mantissa

特别是,当尾数全为 0 时,我们有 0,这是有意的:现在一个在其二进制表示中只有 0 的数字被读作 0。在某种程度上,0 是最小的次正规数字(尽管实际上人们认为它只是一个特例)。

其他特殊情况是指数全为1。如果尾数全为 0,那么你有 +/- 无穷大(取决于符号),如果设置了一些尾数位,你有一个 NaN。