[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