http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54036
Bug #: 54036 Summary: Negating a DFP NAN in C++ produces NAN not -NAN Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: berg...@gcc.gnu.org ReportedBy: berg...@gcc.gnu.org Target: powerpc*-linux, x86*-linux When negating a DFP NaN, we produce another NaN and not a -NaN like we do when using a C test case or with binary floating point (C or C++). This happens on both my power64-linux and x86_64-linux systems. bergner@bns:~> cat dfp-nan.C #include <stdio.h> #include <decimal/decimal> using namespace std; decimal::decimal64 my_nan (void) { decimal::decimal64 z = 0.0DD; decimal::decimal64 v = z/z; return v; } int main (void) { decimal::decimal64 v; v = my_nan (); printf ("value is %Dg\n", v); v = -v; printf ("-value is %Dg\n", v); return 0; } bergner@bns:~> g++ dfp-nan.C -ldfp bergner@bns:~> ./a.out value is nan -value is nan The problem seems to be due to the following lines in libstdc++-v3/include/decimal/decimal.h: #define _DEFINE_DECIMAL_UNARY_OP(_Op, _Tp) \ inline _Tp operator _Op(_Tp __rhs) \ { \ _Tp __tmp; \ __tmp.__setval(0 _Op __rhs.__getval()); \ return __tmp; \ } _DEFINE_DECIMAL_UNARY_OP(+, decimal32) _DEFINE_DECIMAL_UNARY_OP(+, decimal64) _DEFINE_DECIMAL_UNARY_OP(+, decimal128) _DEFINE_DECIMAL_UNARY_OP(-, decimal32) _DEFINE_DECIMAL_UNARY_OP(-, decimal64) _DEFINE_DECIMAL_UNARY_OP(-, decimal128) This causes us to compute a "0 - nan" rather than a "-nan" and "0 - nan" will not produce a -nan. The following change fixes the problem for me: - __tmp.__setval(0 _Op __rhs.__getval()); \ + __tmp.__setval(_Op __rhs.__getval()); \