This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/54036] New: Negating a DFP NAN in C++ produces NAN not -NAN
- From: "bergner at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 19 Jul 2012 20:46:24 +0000
- Subject: [Bug c++/54036] New: Negating a DFP NAN in C++ produces NAN not -NAN
- Auto-submitted: auto-generated
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()); \