1

我正在从包含以下行的文本文件中读取:

      deltaT          0.005;

一旦我在字符串中找到了正确的行,我想用这样的代码读出值:

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

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

那么有没有办法像流插入器一样设置提取器的“精度”?

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

谢谢,玛德琳。

4

2 回答 2

2

这是二进制浮点类型的常见问题:0.005不能完全由 a 表示double,因此从“十进制文字”转换产生的数字与 a 可表示的最相似double

如果您想使用double或其他有限的二进制浮点类型,则没有解决方案,因为0.005在十进制中具有有限形式,但在二进制中是周期性的(并且任何 FP 类型的尾数都是有限的)。

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

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

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

请注意,有几个“任意精度库”可用于处理此类问题,并以仅受可用内存(例如GMP)限制的精度进行数学运算,但您应该考虑额外的复杂性/性能损失是否实际上是合理的获得精度。

另一种解决方案(通常在进行涉及金钱的计算时使用)是使用固定精度类型,将金额存储为一个整数,通过一些小数因子“隐式缩放”(这个概念是您将美分存储为整数而不是美元作为float或任何); 这避免了从十进制到二进制转换的任何意外,因为所有整数都可以用任何基数的有限位数精确表示。

于 2012-11-14T22:27:06.803 回答
0

读取值时没有精度限制之类的东西。无论如何,您都不想拥有它:您希望获得最接近的值。乍一看,这似乎就是你得到的!该值0.005看起来不像可以用二进制浮点精确表示的值。类型double及其朋友表示为 (-1)符号*有效数*2指数,很明显这不能表示所有十进制值。

问题更多出在格式上:您应该让格式选择要格式化的数字位数。假设原始值只是从某个源读取并且是十进制值而不是某些计算的结果,那么您应该在格式化时取回原始值(即尾随零除外)。

于 2012-11-14T22:34:20.490 回答