Opened 8 years ago

Closed 8 years ago

#10085 closed Feature Requests (fixed)

Improve cpp_rational::convert_to<double>

Reported by: marc.glisse@… Owned by: John Maddock
Milestone: To Be Determined Component: multiprecision
Version: Boost 1.55.0 Severity: Problem
Keywords: Cc:

Description

Hello,

the following program prints -nan. If I convert to long double, it prints 1 as expected, but the same problem happens for slightly bigger numerators and denominators. Worse, I can make it return inf or 0 for numbers close to 10 or 0.1. Instead of converting numerator and denominator to double and dividing, it would work better if you had some kind of frexp function that you could apply to both, so the exponents could cancel out without overflowing (that might actually be the same as converting to a cpp_float<53> if it existed).

By the way, it would be nice to document what rounding we can expect from the conversion to double. For cpp_int, can I assume the result is within 1 ulp, rounded towards 0? .5 ulp, rounded to nearest? My goal is to get an interval of double that contains the number (convert_to<boost::numeric::interval_lib::interval<double,P>> basically, except that I don't use boost's type for intervals).

#include <iostream>
#include <limits>
#include <boost/multiprecision/cpp_int.hpp>
typedef boost::multiprecision::cpp_rational NT;

int main(){
  NT x (std::numeric_limits<double>::min());
  x *= x;
  x += 1;
  std::cout << x.convert_to<double>() << '\n';
}

PS: thank you for the quick resolution to the previous ticket!

Change History (4)

comment:1 by John Maddock, 8 years ago

That's exposed a number of conversion related issues that should be handled better, bare with me, the fix isn't so trivial this time...

comment:2 by marc.glisse@…, 8 years ago

Thanks. Indeed the other ticket was more political and this one is more technical. Don't worry about doing this soon, it doesn't have to be in 1.56 or 1.57.

comment:3 by John Maddock, 8 years ago

This should be mostly fixed in this feature branch: https://github.com/boostorg/multiprecision/tree/Issue_10085

Conversions to and from native floating point types and multiprecision ones are supported, conversions to float from rational should be exactly rounded (less than 0.5ulp error) as long as the floating point type is binary and the integer type used by the rational is unbounded.

I plan to do some more testing, and possibly fix some other rational-related issues that have been nagging at me before merging to develop, so it's unlikely at present that this makes 1.56... though you never know.

comment:4 by John Maddock, 8 years ago

Resolution: fixed
Status: newclosed

This should now be fixed in develop.

Note: See TracTickets for help on using tickets.