Boost logo

Boost :

From: Paul A. Bristow (boost_at_[hidden])
Date: 2001-09-05 12:05:22


> -----Original Message-----
> From: jmaurer [mailto:jmaurer]On Behalf Of Jens Maurer
> Sent: Tuesday, September 04, 2001 10:45 PM
> To: boost_at_[hidden]
> Subject: Re: [boost] Math Functions
> > > But can't use this for NaNs???
> >
> > if (product == std::numeric_limits<double>::quiet_NaN() )
> > { // If compare with standard limits quiet_NaN, then
> > result is ALWAYS a
> > NaN!!!
>
> No, the result is always "false". This is a defining property
> of NaNs, they are the only quantities where x == x is false.
> Thus, for IEEE numerics, you can say
> if(x != x)
> throw "x is NaN";
>
> Do make sure to put your compiler into "strict IEEE conformance mode",
> otherwise a greedy optimizer may throw away the "x != x" and replace
> it by "false".
>

To my GREAT surprise this doesn't seem to work for MSVC++!

        double x = std::numeric_limits<double>::quiet_NaN();
        cout << "(x != x) "<< boolalpha << (x != x) << endl;

        double y = 1.;
        cout << "(x != x) "<< boolalpha << (y != y) << endl;

both output return false

This is in debug mode - is this supposed to be strict IEEE conformance?
(I've switched with /Op option on but this makes no difference).

The assembler code for
double x = std::numeric_limits<double>::quiet_NaN();

bool bx = (x == x) is

65: bool bx = (x == x); // expect false for a NaN
0040137E fld qword ptr [x]
00401381 fcomp qword ptr [x]
00401384 fnstsw ax
00401386 test ah,40h
00401389 je main+97h (00401397)
0040138B mov dword ptr [ebp-84h],1
00401395 jmp main+0A1h (004013a1)
00401397 mov dword ptr [ebp-84h],0
004013A1 mov cl,byte ptr [ebp-84h]
004013A7 mov byte ptr [bx],cl
66:

and the result is true.

Or an I doing something silly?

HOwever, I can compare in hex (double quiet NaN -1.#IND == fff8 0000 0000
0000) using a union

union dhex
{
        double d;
        unsigned short usa[4]; // Suits Intel 8087 FP Plauger C Standard p 67.
};

bool isNaN(double d)
{ // Display and test if double is quiet NaN
        dhex dd = {d}; // Initialise double dd.d = 0.0;
        cout.fill('0');
        cout << dd.d << " == " << hex << right
                << setw(4) << dd.usa[3] // SCCC CCCC CCCC FFFF sign & exponent.
                << ' ' << setw(4) << dd.usa[2] // CCCC
                << ' ' << setw(4) << dd.usa[1] // CCCC
                << ' ' << setw(4) << dd.usa[0] // FFFF
                << endl;
                // double quiet NaN -1.#IND == fff8 0000 0000 0000
        return ( (dd.usa[3] == 0xfff8) && (dd.usa[2] == 0x0000) && (dd.usa[1] ==
0x0000) && (dd.usa[0] == 0x0000) );
} // bool isNaN(double d)

which shows

-1.#IND == fff8 0000 0000 0000
std::numeric_limits<double>::quiet_NaN() is NaN true

whereas other values like infinity fail this test.o
1.#INF == 7ff0 0000 0000 0000
+std::numeric_limits<double>::infinity() is NaN false
-1.#INF == fff0 0000 0000 0000
-std::numeric_limits<double>::infinity() is NaN false

And of course can check at start that is IEEE with

        #if ((bool)std::numeric_limits<double>::is_iec559 == false)
        #error "Not IEC559 floating point!" << endl;

Or is there a better way that deals with non-IEEE conforming systems?

Paul

Dr Paul A Bristow, hetp Chromatography
Prizet Farmhouse
Kendal, Cumbria
LA8 8AB UK
+44 1539 561830
Mobile +44 7714 33 02 04
mailto:pbristow_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk