2012-11-14 26 views
1

我从其中包含以下行的文本文件阅读:C++ istream提取精度?

 deltaT   0.005; 

一旦我得到了一个字符串中正确的路线,我想读出这样的代码值:

 double deltaT; 
     stringstream ss(line); 
     ss >> tag;    //Contains:   deltaT 
     ss >> deltaT;    //Should contain: 0.005 

在调试过程中,我看到的DeltaT包含:0.0050000000000000001

那么,有没有一种方法来设置提取的“精确”像有一个流插入?

或者什么是保证文本文件中的值是我的程序中的双精度值的最佳方法。

谢谢, 玛德琳。

+2

[这可能会告诉你为什么你会看到你所看到的。](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。对于SO Q&A浮点精度的主题,您可能会发现以下[搜索结果](http://stackoverflow.com/search?q=Floating+Point+Precision)也很有趣。 – WhozCraig

回答

2

这就是二进制浮点类型的常见问题:0.005是不是由double精确表示,所以从“十进制文本”转换产生由double最相似的数字表示的。

有没有解决办法,如果你想使用double或其它有限,二进制浮点类型,因为0.005在小数有限的形式,但is periodic in binary(以及任何FP型的尾数是有限的)。

要了解这是可能的,考虑分数1/3:在基座3它具有有限的表示,而在基座10是周期性:

(1/3) = 0.33333 .. 。 = 0.1

现在,任何“常规”浮点型具有用于尾数(即显著数字存储)只有一些有限的空间,所以每一个周期数必须被截断(实际上四舍五入) 在某一点;这会导致您看到的精度损失。

请注意,有几个“任意精度库”可用于处理这类问题,并且仅通过可用内存限制精度(例如GMP),但是您应该考虑是否额外复杂性/性能损失是实际上由精确度的增加来证明是合理的。

另一种解决方案(通常用于计算涉及货币的计算)是使用固定精度类型,将数量作为整数“隐式缩放”一些十进制因子(概念是将美分作为整数存储美元为float或其他);这避免了从小数转换为二进制转换的任何惊喜,因为所有整数都可以在任何基数中用有限数量的数字完全表示。

0

读取数值时,不存在对精度的限制。不管怎样,你都不想这样做:你想得到最接近的价值。从简单的看来,这似乎是你得到的!值0.005看起来不像一个可以完全用二进制浮点表示的值。该类型double和它的朋友表示为(-1)标志 * 尾数 * 2 指数,这是显而易见,这并不能代表所有的十进制值。

问题更多与格式:你应该让格式选择感觉格式化多少数字。假设原始值是从某个源读取的,并且是一个十进制值而不是某些计算的结果,那么在格式化时应该返回原始值(除了尾部零,即,)。