J
James Kanze
No, the outcome is implementation defined. Arguably, your
implementation has the _better_ result.
The outcome is definitely not implementation defined. The
accuracy (and repeatability?) of expression evaluation is
unspecified.
Yup, and that's ok with the standard by [5/10].
Within an expression. As far as I know, the value with extended
precision *must* be rounded to double when it is used to
initialize a double, e.g. the return value.
In g+++, this is under control of the option -ffloat-store.
Regretfully, the default results in the non-conformant and
unexpected behavior, and the documentation of the option
suggests that it usually doesn't matter, where as it often does.
Actually, _that_ is not the reason I heard. I thaught equality
is very likely not what you want anyway because of what the
floating point numbers in your program represent.
Actually, I've yet to hear anyone who really knows floating
point make such a recommendation. (It certainly doesn't apply
here, because there is no comparison for equality in the
original code.) What I have heard is that to use machine
floating point, you need to understand it first. And that it
can have some rather unexpected properties; the fact that you
can't actually know the precision of intermediate values---that
a double isn't necessarily a double---is perhaps the most
surprising ones (and is, of course, not inherent in floating
point, but rather a particularity of one particular
implementation).
However, it is true that the excess precision in registers can
screw up comparisons. But it can be prevented forcing a
write-reread cycle.
Not with g++, unless you specify -ffloat-store.
The program
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
bool equal ( double const & lhs, double const & rhs ) {
return ( lhs == rhs );
}
int main ( void ) {
double x = 1;
double y = 1;
cout
<< boolalpha
<< equal( sin(x)+cos(y), sin(x)+cos(y) ) << '\n';
}
prints true. I am not certain whether the standard requires
that or not, but since the OP also uses gcc on an intel
platform, the example pertains to the behavior he observes.
Note, however, that the above doesn't force a write-reread cycle
any more than the original, at least according to the standard.
(None of the writes or reads are "observable behavior".) It
would be interesting to look at the generated code under
optimization; I wouldn't be surprised if g++ drops both writes,
and that it works because neither value has been truncated to
double, not because both have been.