2011-08-20 63 views
0

可能重复初始化它:
Floating point inaccuracy examples龙双不打印为常数我

林有一个问题...当我编译SRC,变量显示ISN “T相同,我初始化,看到它:

#include <iostream> 

    using namespace std; 

    int main() 
    { 
     long double mynum = 4.7; 
     cout.setf(ios::fixed,ios::floatfield); 
     cout.precision(20); 
     cout << mynum << endl; 
    } 

然后:

[[email protected] ~]$ ./a.out 
4.70000000000000017764 

如何解决?我想“COUT”显示4.700000 ......

+8

...再次。 –

+0

这个问题有六百万亿投资。搜索“浮点不精确”。 – Puppy

+1

“长双倍比我的字面常量更精确”的角度并不是在600万亿次的所有困境中都存在。 –

回答

5

您的变量是long double,但文字4.7的默认精度仅为double。由于您将其打印为long double,因此解释会选择使用足够的有效数字来打印它,以将其与相邻的long double值区分开,即使这些相邻值不可能是double s。

+1

有斑点,使用正确的文字可以获得预期的19位精度! –

2

大多数平台,包括你,可以只有代表这些人恰恰是浮点数其中有一个短暂的,有限的二进制展开,即它们是两个大国的有限资金。 4.7是不是这样的一个数字,所以它不能被你的平台上准确地表示,如果你要求过多的精度(20是你的尾数64位,log_10(64)为19.27太多了),那么你将不可避免地面临小错误。 (但是,正如@Henning所说,当你从一个(非long)double中分配时,你已经失去了精度;你应该把你的字面常量写成一个long double:4.7L然后你应该只看到一个错误第二位)

1

某些数字不能用二进制表示。显然,4.7是其中之一。你看到的是最接近4.7的数字。

除了将精度设置为较低的数字之外,您无能为力。

2

float S和double s为二进制浮点类型,即它们存储尾数和在碱的指数2.

这意味着,不能被精确表示成尾数的有限位数任何十进制数将近似;您显示的问题来自于此:4.7不能完全代表double的尾数(文字4.7的类型为double,赞誉@Henning Makholm用于发现它),因此使用最接近的近似值。

为了更好地可视化的问题:在基体3,是2/3具有有限表示的数量(即0.2 ),而在基座10它是一个周期性的数目(0,6666666 ...);如果您只有有限的数字空间,则必须执行一个近似值,即0,66666667。这里完全一样,源代码为10,“目标”基数为2.

如果有特殊需要避免这种近似值(例如,在处理小数金额时)特殊decimal类型可以被使用,该商店尾数和指数在基座10(C++不提供这种类型其自己的,但也有许多可用decimal类的净);仍然,对于“正常”/科学计算,使用二元FP类型,因为它们更快,更节省空间。

2

双打的内部表示不允许“精确”表示4.7。 “最接近的”是4.70000000000000017764。实际上,当你有64位双打时,不需要看20的精度。最大有效精度约为15.尝试使用12左右,

cout.precision(12); 

你应该得到你想看到的。