双精度 - 小数位 [英] Double precision - decimal places

查看:231
本文介绍了双精度 - 小数位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我已经读取的数据类型double的值具有15个小数位数的近似精度。但是,当使用无理数(例如1.0 / 7.0)时,我发现该变量保存的值为0.14285714285714285 - 这是17个位置(通过调试器)。



我想知道为什么它在内部表示为17个地方,为什么15的精度总是写在〜15?

解决方案

IEEE double具有53个有效位(这是 < cfloat> 中的DBL_MANT_DIG 的值)。这大约是15.95个十进制数字(log10(2 53 ));实现将 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆