为了在网络上传输数据,我将双精度值转换为字符串,然后发送,然后在接收端将其转换回双精度值。到目前一切尚好。但我偶然发现了一些我无法解释的奇怪行为
整个示例代码可以在here中找到。我做的是:通过ostringstream写一个双精度值给字符串,然后用istringstream读取它,值会改变,但如果我使用函数"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'”请不要回答为什么IEEE754不准确的问题。
发布于 2011-10-13 00:17:25
为什么它们可能不同:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.16
浮点是一种近似值...
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
浮点数会让您感到惊讶的原因是,浮点数和双精度值通常使用有限精度的二进制格式表示。换句话说,浮点数不是实数。例如,在您的机器的浮点格式中,可能不可能精确地表示数字0.1。通过类比的方式,不可能用十进制格式精确地表示数字的三分之一(除非您使用无限数量的数字)……信息是,一些浮点数并不总是被精确地表示,所以比较并不总是按照您希望的那样进行。换句话说,如果计算机实际上将10.0乘以1.0/10.0,它可能不会准确地得到1.0。
如何比较浮点数:
http://c-faq.com/fp/strangefp.html
与存储在内存中的双精度值相比,
...some机器在浮点计算寄存器中的可用精度更高,这可能会导致浮点不平等,因为看起来两个值只要相等即可。
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)是可能的。从实际的角度来看,当x和y的幅度明显大于epsilon时,通常不会发生这种情况,但您的里程可能会有所不同。
https://stackoverflow.com/questions/7742908
复制相似问题