为了通过网络传输数据,我将double转换为string,发送并在接收方将其转换回double。
到现在为止还挺好。
但是我偶然发现了一些我无法解释的奇怪行为
整个示例代码可以在here中找到。
我所做的:
通过ostringstream
写一个 double 字符串,然后用istringstream
读入
值(value)变化
但是,如果我使用函数“strtod(...)”,它将起作用。 (具有相同的outstring
)
示例(可以在here中找到整个代码):
double d0 = 0.0070000000000000001;
out << d0;
std::istringstream in (out.str());
in.precision(Prec);
double d0X_ = strtod(test1.c_str(),NULL);
in >> d0_;
assert(d0 == d0X_); // this is ok
assert(d0 == d0_); //this fails
我不知道为什么会这样。
问题是:“为什么'istream >>'导致另一个结果为'strtod'”
请不要回答为什么IEEE 754不够精确的问题。
最佳答案
为什么它们可能有所不同:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.16
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
如何比较浮点:
http://c-faq.com/fp/strangefp.html
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
这是错误的方法:
void dubious(double x, double y)
{
...
if (x == y) // Dubious!
foo();
...
}
如果您真正想要的是确保它们彼此“非常接近”(例如,如果变量a包含值1.0 / 10.0,并且您想查看是否(10 * a == 1)),则可能想做一些比以上更出色的事情:
void smarter(double x, double y)
{
...
if (isEqual(x, y)) // Smarter!
foo();
...
}
定义isEqual()函数的方法有很多,包括:
#include <cmath> /* for std::abs(double) */
inline bool isEqual(double x, double y)
{
const double epsilon = /* some small number such as 1e-5 */;
return std::abs(x - y) <= epsilon * std::abs(x);
// see Knuth section 4.2.2 pages 217-218
}
注意:以上解决方案不是完全对称的,这意味着有可能使用isEqual(x,y)!= isEqual(y,x)。从实际的 Angular 来看,当x和y的幅度明显大于epsilon时,通常不会发生这种情况,但是里程数可能会有所不同。
关于c++ - double>字符串> double转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7742908/