为什么浮点数的有效数是 7 或 6

hel*_*ter 1 c floating-point precision

我在维基百科日志 2 24 = 7.22 中看到了这一点 。

我不知道为什么我们应该计算 2^24 以及为什么我们应该取 log10......我真的很需要你的帮助。

chu*_*ica 5

为什么浮点数的有效数是 7 或 6 (?)

考虑使用鸽巢原理的一些想法:

  1. binary32 float可以精确编码大约 2 32 个不同的数字。可以在文本中写入的数字 42.0, 1.0, 3.1415623... 是无限的,即使我们将自己限制在 -10 38 ... +10 38这样的范围内。任何时间代码都有一个文本值,例如,它被编码到附近的,这可能不是完全相同的文本值。问题是:我们可以编码多少个数字并仍然保持独特0.1ffloatfloat
  2. 对于各种 2 的幂范围,通常对2 23 (8,388,608) 个值进行线性编码。
  3. 在 [1.0 ... 2.0) 范围内,2 23 (8,388,608) 个值被线性编码。
  4. 在 [2 33或 8,589,934,592 ... 2 34或 17,179,869,184)范围内,2 23 (8,388,608) 个值再次被线性编码:彼此相距 1024.0。在子范围 [9,000,000,000 和 10,000,000,000) 中,大约有 976,562 个不同的值。

把这个放在一起...

  1. 作为文本,范围 [1.000_000 ... 2.000_000),使用 1 个前导数字和 6 个尾随数字,有 1,000,000 个不同的值。Per #3,在同一范围内,有 8,388,608 个不同的float存在,允许每个文本值映射到不同的float. 在这个范围内,我们可以使用 7 位数字

  2. 作为文本,范围 [9,000,000*10 3和 10,000,000*10 3 ),使用 1 个前导数字和 6 个尾随数字,有 1,000,000 个不同的值。根据 #4,在同一范围内,不同的float值少于 1,000,000 个。因此,一些十进制文本值将转换为相同的float. 在这个范围内,我们可以使用 6 位不是 7 位数字进行特殊转换。

典型的最坏情况float6 位有效数字。要找到 的限制float

#include <float.h>
printf("FLT_DIG = %d\n", FLT_DIG);  // this commonly prints 6
Run Code Online (Sandbox Code Playgroud)

...不知道为什么我们应该计算 2^24 以及为什么我们应该取 log10

2^24 是对 commonfloat及其 24 位二进制精度的概括,对应于具有 7.22... 数字的奇特十进制系统。我们使用log10二进制 文本float十进制文本进行比较。

2 24 == 10 7.22...

然而,我们应该采取2 24。让我们看看FLT_DIGC11dr §5.2.4.2.2 11 中是如何定义的:

十进制数字的数量,q,这样任何具有q十进制数字的浮点数都可以四舍五入为具有p基数b数字的浮点数,然后再返回而不更改为q十进制数字,

p log 10 b ........如果 b 是 10 的幂
?( p ? 1) log 10 b ?... 否则

注意“log 10 2 24 ”与“24 log 10 2”相同。

作为 a float,值在 2 的幂之间线性分布,如#2,3,4 所示。

作为文本,值在 10 的幂之间线性分布,例如 [1.000000 ... 9.999999]*10 some_exponent的 7 个有效数字值。

这两组的转换发生在不同的值。1,2,4,8,16,32... 与 1,10,100, ... 在确定最坏情况时,我们从 24 位中减去 1以解决未对齐的问题。

?( p ? 1) log 10 b ? --> floor((24 ? 1) log10(2))--> floor(6.923...)--> 6.

如果我们float使用的基数是 10、100 或 1000,而不是非常常见的 2,那么这两个组的转换发生在相同的值上,我们不会减去一个。

  • 谢谢你先生!我曾想过使用“地图”来解决这个问题,但我不能像你一样清晰地思考。你的回答确实给了我一个新的方式来思考这个有趣的问题。真诚地谢谢你。 (2认同)