Sergey
Sergey

Reputation: 8238

Convert double to mpf_class precisely

What is the correct way to initialize GMP floating point variables (mpf_t or mpf_class, does not matter) from double?

Code:

#include <iostream>
#include <gmpxx.h>

int main()
{
        double d=0.1;

        //1024 bits is more that 300 decimal digits
        mpf_set_default_prec(1024);

        mpf_class m(d);

        //after initializing mpf_class variable, set default output precision
        std::cout.precision(50);
        std::cout.setf(std::ios_base::scientific);

        std::cout << m << std::endl;

        return 0;
}

The output is:

1.00000000000000005551115123125782702118158340454102e-01

It would be okay, if I printed d directly, but in the m variable 300 decimal digits of mantissa are trusted! I use GMP for an iterative numerical method, so these non-zeros introduce mistake and make the method converge slowly.

If I initilize m as mpf_class m("0.1");, the output is:

1.00000000000000000000000000000000000000000000000000e-01

So the problem is not in operator<< overload for mpf_class. The problem exists not only for initializing, but for assigning too.

At present I use the following:

mpf_class linsys::DtoGMP(const double& arg)
{
        char buf[512];
        sprintf(buf,"%.15le\n",arg);
        return mpf_class(buf);
}

for correct conversion.

Is there a faster and/or more native way to do it?

My OS is OpenSUSE 12.1, compiler: gcc 4.6.2

Upvotes: 1

Views: 2012

Answers (2)

Igor Sayko
Igor Sayko

Reputation: 1

You may use this method

mpf_class a; double d=0.1; a=static_cast<mpf_class>(d*10)/static_cast<mpf_class>(10); this method can be used if you know how many decimal places a double has

Upvotes: -1

Cogwheel
Cogwheel

Reputation: 23217

If you print out the double with that same precision, you should see the same strange-looking number. That's simply because 0.1 can't be accurately represented in floating point. The mpf_class is accurately reproducing the value stored in the double. It's the double that isn't matching your expectations.

There's probably a way to specify a precision to gmp or some way to round the input. I'm not sure where to look though.

Edit

mpf_class has a constructor with a precision parameter: http://www.gnu.org/software/gmp/manual/html_node/C---Interface-Floats.html

Upvotes: 2

Related Questions