【发布时间】:2014-05-21 09:30:21
【问题描述】:
我必须从文本文件中读取一些数据(精度为double)。有时,当使用atof 从string 转换为double 时,我会得到奇怪的结果。以下是演示问题的代码 sn-p - 请注意,我使用的是 GNU C++ 4.8.1 编译器。该代码仅打印出介于 -0.1 和 0 之间的数字,步长为 0.01;因此,仅需要 9 个数字。
#include <iostream>
#include <cstdlib>
int main() {
int y;
double a, b = 0.0, x = 1e-2, z;
double a_string = atof("-0.1");
double a_inline = -0.1;
std::cout << "Inline:: ";
a = a_inline;
for (y = 1 ; (z = a + y * x) < b; ++y){
std::cout << y << ": " << z << " | ";
}
std::cout << "\nString:: ";
a = a_string;
for (y = 1 ; (z = a + y * x) < b; ++y){
std::cout << y << ": " << z << " | ";
}
return 0;
}
结果是
Inline:: 1: -0.09 | 2: -0.08 | 3: -0.07 | 4: -0.06 | 5: -0.05 | 6: -0.04 | 7: -0.03 | 8: -0.02 | 9: -0.01 |
String:: 1: -0.09 | 2: -0.08 | 3: -0.07 | 4: -0.06 | 5: -0.05 | 6: -0.04 | 7: -0.03 | 8: -0.02 | 9: -0.01 | 10: -3.46945e-18 |
请注意,基于字符串赋值 (a_string) 的 for 循环比基于内联赋值 (a_inline) 的循环多运行一次——注意最后一个数字 -3.46945e-18。阅读了其他有关字符串到双精度转换的相关帖子后,我仍然无法弄清楚为什么会发生这种情况。
【问题讨论】:
-
注意:它在我的装备上表现如预期(每个循环 9 个值)。 (Apple LLVM 版本 5.1 (clang-503.0.40)(基于 LLVM 3.4svn)),编译为 x64。有趣的是,Coliru 与 ideone.com 的结果不同。
-
它对我也很有效,GNU C++ 4.3.2, x64
-
在我看来 atof("-0.1") 必须作为字符串解析器工作,所以它不能像从 "-0.1" 字符串中获取 -0.1 值那样工作,它通过以下方式获得最终值将一些值行相加并将其乘以-1.0(在您的情况下为-1.0 * 0.1)。我认为这个乘法是原因。之后,您的字符串值将类似于 -0.100000000000001。
-
它对我也有好处,VS2012,x64
-
@Fomin Arseniy 循环中没有明显的积累。
标签: c++ string double data-conversion