Search code examples
cgmpmpfr

How MPFR Library Calculation Accuracy Works


I confess that I am having trouble understanding the MPFR library, I am trying to calculate the square root of a large number but I am not sure how to define the precision of the mpft_t root variable or what is the best way of rounding.

my code is as follows:


#include <stdio.h>
#include <stdlib.h>
#include <mpfr.h>


int main(){

    mpfr_t bigNumber, bigNumber2, root2;

    unsigned long int size = 1000000;

    mpfr_init2(bigNumber, size);
    mpfr_init2(bigNumber2, size);
    mpfr_init2(root2, size);

    mpfr_ui_pow_ui(bigNumber, 8, 20000, MPFR_RNDZ);

    mpfr_sqrt(root2, bigNumber, MPFR_RNDA);

    mpfr_pow_ui(bigNumber2, root2, 2, MPFR_RNDA);

    return 0;
}

But regardless of the precision set for mpz_t root, the result is often not satisfactory.

The result of mpfr_pow_ui (bigNumber2, root, 2, MPFR_RNDA) is most often different than mpfr_t bigNumber, and I don't mean the floating value, but the entire part.

How to find out the precision needed to perform a certain calculation?

what is the best form of rounding for this calculation?

why does this inaccuracy happen?


Solution

  • The code works fine (on GCC 9.3.0 and MPFR 4.1.0) and gives back the original number.

    #include <stdio.h>
    #include <stdlib.h>
    #include <mpfr.h>
    
    
    int main()
    {
        mpfr_t bigNumber, bigNumber2, root2;
        unsigned long int size = 100000;
        mpfr_init2(bigNumber, size);
        mpfr_init2(bigNumber2, size);
        mpfr_init2(root2, size);
        mpfr_ui_pow_ui(bigNumber, 8, 20000, MPFR_RNDD);
        mpfr_out_str (stdout, 10, 0, bigNumber, MPFR_RNDD);
        putchar ('\n');
        putchar ('\n');
        putchar ('\n');
        mpfr_sqrt(root2, bigNumber, MPFR_RNDD);
        mpfr_out_str (stdout, 10, 0, root2, MPFR_RNDD);
        putchar ('\n');
        putchar ('\n');
        putchar ('\n');
        mpfr_pow_ui(bigNumber2, root2, 2, MPFR_RNDD);
        mpfr_out_str (stdout, 10, 0, bigNumber2, MPFR_RNDD);
        putchar ('\n');
        putchar ('\n');
        putchar ('\n');
        putchar ('\n');
        return 0;
    }