[Bug c++/54036] New: Negating a DFP NAN in C++ produces NAN not -NAN

bergner at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Jul 19 20:46:00 GMT 2012


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: bergner@gcc.gnu.org
        ReportedBy: bergner@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());    \



More information about the Gcc-bugs mailing list