[ntl] quad_float to_long() observations

Olivier Langlois olivier at olivierlanglois.net
Thu Jun 17 22:12:45 CDT 2010


Hi,

I just notice that I was not getting the same behavior from quad_float that I 
am observing with native built-in double type when converting a negative 
double to long.

With built-in double, the fractional part is always discarded in the direction 
of zero (at least on my platform Intel x86 64-bits Linux with GNU g++).

P.S.: Take this observation with a grain of salt since The Annotated C++ 
Reference manual says that the direction of the truncation varies from machine 
to machine.

Anyway, I have written a small test drive to test the behavior of a given 
platform.

double_trunc_test.cpp:

#include <iostream>

int main( int argc, char *argv[] )
{
    double a = -1.9999;
    double b =  1.9999;

    if( static_cast<long>(a) == -1 )
    {
        std::cout << "negative double to long conversion discards the 
fractional part toward 0.\n";
    }
    else
    {
        std::cout << "negative double to long conversion discards the 
fractional part toward negative infinity.\n";
    }

    if( static_cast<long>(b) == 1 )
    {
        std::cout << "positive double to long conversion discards the 
fractional part toward 0.\n";
    }
    else
    {
        std::cout << "positive double to long conversion discards the 
fractional part toward positive infinity.\n";
    }

    return 0;
}

With quad_float class to_long() the fractional truncation looks to always 
happen toward the negative infinity.

I have stumbled on that difference by converting

// 64-bits
std::numeric_limits<long>::min()

in quad_float and then subtracting 0.999999 from it.

When calling to_long() on the result, it did cause an underflow and did give 
the wrong result.

This seems to be caused by the usage of the floor() function in to_long(). I am 
not fully understanding how quad_float is working but I think that by using 
implicit typecast instead of floor() that could make quad_float behave like the 
built-in double no matter what is the behavior on a given machine.

long to_long(const quad_float& x)
{
   double fhi, flo;

   fhi = floor(x.hi);

   if (fhi == x.hi)
      flo = floor(x.lo);
   else
      flo = 0;
...
}

This is not a bug since the C++ standard does not specify how conversion 
should behave but I just want to start a discussion on that issue and hear the 
opinion of other users.

Thank you,
Olivier Langlois
http://blog.olivierlanglois.net



More information about the ntl mailing list