浮点精度是可变的还是不变的,为什么?
通常,给定相同 2 次幂范围内的任何数字,浮点精度是不变的 - 一个固定值。绝对精度随着每步的 2 次方而变化。在整个 FP 范围内,精度大约与幅度相关。将这种相对二进制精度与十进制精度相关联会导致在十进制DBL_DIG
数字之间变化DBL_DECIMAL_DIG
- 通常为 15 到 17。
什么是精度?对于 FP,讨论相对精度是最有意义的。
浮点数的形式为:
符号 * 有效数 * pow(base,exponent)
它们具有对数分布。在100.0 和 3000.0 之间(范围为 30 倍)与 2.0 和 60.0 之间的浮点数一样多。无论底层存储表示如何,这都是正确的。
1.23456789e100
具有与 大致相同的相对精度1.23456789e-100
。
大多数计算机实现double
为binary64。此格式具有 53 位二进制精度。
1.0 和 2.0 之间的n
数字在 ((2.0-1.0)/pow(2,52) 中具有 1 部分的绝对精度。64.0
和 128.0 之间的数字也n
具有 ((128.0- 64.0)/pow(2,52)。
即使是 2 次方之间的一组数字,也具有相同的绝对精度。
在 FP 数的整个正常范围内,这近似于统一的相对精度。
当这些数字表示为十进制时,精度会摆动:数字 1.0 到 2.0 的绝对精度比数字 2.0 到 4.0 多 1 位。比 4.0 到 8.0 多 2 位,等等。
C 提供DBL_DIG
, DBL_DECIMAL_DIG
, 以及它们float
和long double
对应物。 DBL_DIG
表示最小相对小数精度。 DBL_DECIMAL_DIG
可以认为是最大相对小数精度。
通常,这意味着给定double
的精度为 15 到 17 位十进制数字。
考虑1.0
它的下一个可表示double
的,直到第 17 位有效十进制数字才改变。每个下一个double
是pow(2,-52)
或大约2.2204e-16
分开。
/*
1 234567890123456789 */
1.000000000000000000...
1.000000000000000222...
现在考虑"8.521812787393891"
将其下一个可表示的数字视为使用 16 个有效十进制数字的十进制字符串。这两个字符串,转换为double
相同, 8.521812787393891142073699...
即使它们在第 16 位不同。说这double
有 16 位精度被夸大了。
/*
1 234567890123456789 */
8.521812787393891
8.521812787393891142073699...
8.521812787393892