C 中类型的描述float
提到有效数字的数量是6
。然而,
float f = 12345.6;
然后使用 printf() 打印它不打印12345.6
,它打印12345.599609
。那么double
对于浮点类型来说,“6 位有效数字”(或“15 位”)是什么意思呢?
C 中类型的描述float
提到有效数字的数量是6
。然而,
float f = 12345.6;
然后使用 printf() 打印它不打印12345.6
,它打印12345.599609
。那么double
对于浮点类型来说,“6 位有效数字”(或“15 位”)是什么意思呢?
6 位有效数字表示最大误差约为 +/- 0.0001%。单个浮点值实际上具有大约 7.2 位的精度(source)。这意味着误差约为 +/- 12345.6/10^7 = 0.00123456。这是您的错误(0.000391)的顺序。
根据标准,并非所有十进制数都可以准确地存储在内存中。根据表示的大小,误差可以达到某个最大值。因为float
这是0.0001%
(6 位有效数字 = 10^-6
= 10^-4 %
)。
在您的情况下,错误(12345.6 - 12345.599609) / 12345.6 = 3.16e-08
远低于浮点数的最大错误。
您所看到的实际上并不是有效数字的任何问题,而是计算机上的数字以二进制形式存储的事实,并且 3/5 (= 0.6) 没有有限的二进制表示。二进制的 3/5 看起来像 0.100110011001...,“1001”模式永远重复。这个序列相当于 0.599999... 重复。在任何与精度相关的错误出现之前,您实际上已经到达小数点右侧的三位小数。
这类似于没有 1/3 的有限 base-10 表示;我们有 0.3333 永远重复。
这里的问题是你不能保证一个数字可以存储在一个浮点数中。正如IEEE 754解释的那样,您需要用尾数、底数和指数来表示这个数字。该数字printf(...)
显示您是存储的真实浮点数。您不能保证浮点数中有多个有效数字。