双精度 - 小数位 [英] Double precision - decimal places
问题描述
从我已经读取的数据类型double的值具有15个小数位数的近似精度。但是,当使用无理数(例如1.0 / 7.0)时,我发现该变量保存的值为0.14285714285714285 - 这是17个位置(通过调试器)。
我想知道为什么它在内部表示为17个地方,为什么15的精度总是写在〜15?
IEEE double具有53个有效位(这是
的值)。这大约是15.95个十进制数字(log10(2 53 ));实现将< cfloat>
中的DBL_MANT_DIG 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\\\
,FLT_RADIX);
printf(DBL_DIG =%d\\\
,DBL_DIG);
printf(DBL_MANT_DIG =%d\\\
,DBL_MANT_DIG);
printf(%。17g \\\
%.17g \\\
%.17g\\\
,nextafter(x,0.0),x,nextafter(x,1.0)
}
给我的系统输出:
<$ c $ p>
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
其中显示精确度的十六位小数。
From what I have read, a value of data type double has an approximate precision of 15 decimal places. However, when use an irrational number, such as 1.0/7.0, I find that the variable holds the value of 0.14285714285714285 - which is 17 places (via the debugger).
I would like to know why it is represented as 17 places internally, and why a precision of 15 is always written at ~15?
An IEEE double has 53 significant bits (that's the value of DBL_MANT_DIG
in <cfloat>
). That's approximately 15.95 decimal digits (log10(253)); the implementation sets DBL_DIG
to 15, not 16, because it has to round down. So you have nearly an extra decimal digit of precision (beyond what's implied by DBL_DIG==15
) because of that.
The nextafter()
function computes the nearest representable number to a given number; it can be used to show just how precise a given number is.
This program:
#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));
}
gives me this output on my system:
FLT_RADIX = 2
DBL_DIG = 15
DBL_MANT_DIG = 53
0.14285714285714282
0.14285714285714285
0.14285714285714288
(You can replace %.17g
by, say, %.64g
to see more digits, none of which are significant.)
As you can see, the last displayed decimal digit changes by 3 with each consecutive value. The fact that the last displayed digit of 1.0/7.0
(5
) happens to match the mathematical value is largely coincidental; it was a lucky guess. And the correct rounded digit is 6
, not 5
. Replacing 1.0/7.0
by 1.0/3.0
gives this output:
FLT_RADIX = 2
DBL_DIG = 15
DBL_MANT_DIG = 53
0.33333333333333326
0.33333333333333331
0.33333333333333337
which shows about 16 decimal digits of precision, as you'd expect.
这篇关于双精度 - 小数位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!