根据我的阅读,数据类型 double 的值具有大约 15 位小数的精度。但是,当我使用十进制表示重复的数字(例如 1.0/7.0)时,我发现该变量包含 0.14285714285714285 的值——即 17 位(通过调试器)。
我想知道为什么它在内部表示为 17 位,为什么 15 的精度总是写在 ~15 处?
最佳答案
IEEE double 有 53 个有效位(即 DBL_MANT_DIG
中的 <cfloat>
的值)。这大约是 15.95 个十进制数字 (log10(253));实现集DBL_DIG
到 15,而不是 16,因为它必须向下舍入。因此,您的精度几乎多了一个十进制数字(超出 DBL_DIG==15
所暗示的)。
nextafter()
函数计算最接近给定数字的可表示数字;它可以用来显示给定数字的精确程度。
这个程序:
#include <cstdio>
#include <cfloat>
#include <cmath>
int main() {
double x = 1.0/7.0;
printf("FLT_RADIX = %d\n", FLT_RADIX);
printf("DBL_DIG = %d\n", DBL_DIG);
printf("DBL_MANT_DIG = %d\n", DBL_MANT_DIG);
printf("%.17g\n%.17g\n%.17g\n", nextafter(x, 0.0), x, nextafter(x, 1.0));
}
在我的系统上给我这个输出:
FLT_RADIX = 2
DBL_DIG = 15
DBL_MANT_DIG = 53
0.14285714285714282
0.14285714285714285
0.14285714285714288
(您可以将 %.17g
替换为 %.64g
以查看更多数字,但这些数字都不重要。)
如您所见,最后显示的十进制数字随每个连续值变化 3。 1.0/7.0
的最后一个显示数字的事实( 5
) 恰好匹配数学值很大程度上是巧合;这是一个幸运的猜测。正确的四舍五入数字是6
,而不是 5
.更换1.0/7.0
由 1.0/3.0
给出这个输出:
FLT_RADIX = 2
DBL_DIG = 15
DBL_MANT_DIG = 53
0.33333333333333326
0.33333333333333331
0.33333333333333337
如您所料,它显示了大约 16 位小数的精度。
关于c++ - double - 小数位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9999221/