Trying to read in a decimal number on the command line and getting a
strange response.  Just ever so slightly wrong result.

Some other code I have was acting strange so I did this bit :

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <math.h>
#include <gmp.h>
#include <mpfr.h>

#define PREC 113 /* lowest reasonable precision */

int main (int argc, char *argv[])
{
    uint64_t bit_prec = PREC;
    mpfr_t input_m;
    int inex; /* mpfr retval */

    inex = mpfr_init_set_si(input_m, (long)0, MPFR_RNDN);
    /* check if a test integer was on the command line */
    if (argc<2){
        fprintf(stderr,"FAIL : test number and optional bit precision?\n");
        fprintf(stderr,"     : %s <integer> <bit precision>\n", argv[0]);
        fprintf(stderr,"     : default bit precision is %i\n\n", PREC);
        return (EXIT_FAILURE);
    }

    /* check if a bit precision parameter was on the command line */
    if (argc>2){
        bit_prec = (int)strtol(argv[2], (char **)NULL, 10);
        if (bit_prec>1023){
            bit_prec = 1024;
            printf("\nWARNING : limit precision to 1024 bits.\n");
        }
    } else {
        bit_prec = PREC;
    }
    printf("\nWe shall use %i bits of precision.\n", bit_prec);
    mpfr_set_default_prec((mpfr_prec_t)bit_prec);

    if (argc>1){
/* int mpfr_set_str(mpfr_t rop, const char *s, int base, mpfr_rnd_t rnd)
         *
         *   Set rop to the value of the string s in base base, rounded
         *   in the direction rnd. See the documentation of mpfr_strtofr
         *   for a detailed description of the valid string formats.
         *   Contrary to mpfr_strtofr, mpfr_set_str requires the whole
         *   string to represent a valid floating-point number.
         *
         *   The meaning of the return value differs from other MPFR
         *   functions: it is 0 if the entire string up to the final null
         *   character is a valid number in base base;
         *   otherwise it is -1, and rop may have changed (users interested
         *   in the ternary value should use mpfr_strtofr instead).    */
        inex = mpfr_set_str(input_m, argv[1], 10, MPFR_RNDN);
        if ( inex < 0 ) {
            printf("\nFAIL : some mysterious problem happened!\n");
            printf("     : we tried to interpret %s\n", argv[1]);
            printf("     : however we seemed to get ");
            mpfr_printf("%.Rf\n", input_m);
            return (EXIT_FAILURE);
        }

        if (mpfr_number_p(input_m)==0){
            printf("\nFAIL : provide a reasonable decimal number.\n");
            return (EXIT_FAILURE);
        }

    } else {
        printf("\nFAIL : provide a nice base ten number!\n");
        printf("     : %s <some number> <bit precision>\n", argv[0]);
        return (EXIT_FAILURE);
    }

    printf("You seem to have entered %s\n", argv[1]);
    printf("Where mpfr_set_str() seems to see ");
    mpfr_printf("%.Rf\n", input_m);

    return (EXIT_SUCCESS);
}


So seems to work up until the numbers are large :

nix$ ./mpfr_set_str 1844674407370999

We shall use 113 bits of precision.
You seem to have entered 1844674407370999
Where mpfr_set_str() seems to see 1844674407370999.000000
nix$

Fine.

However :

nix$ ./mpfr_set_str 18446744073709551601

We shall use 113 bits of precision.
You seem to have entered 18446744073709551601
Where mpfr_set_str() seems to see 18446744073709551616.000000
nix$

Not sure where those last two digits went wrong.

nix$ ./mpfr_set_str 1844674407370955160

We shall use 113 bits of precision.
You seem to have entered 1844674407370955160
Where mpfr_set_str() seems to see 1844674407370955264.000000
nix$

nix$
nix$ ./mpfr_set_str 999999999999999

We shall use 113 bits of precision.
You seem to have entered 999999999999999
Where mpfr_set_str() seems to see 999999999999999.000000
nix$
nix$ ./mpfr_set_str 9999999999999990

We shall use 113 bits of precision.
You seem to have entered 9999999999999990
Where mpfr_set_str() seems to see 9999999999999990.000000
nix$ ./mpfr_set_str 9999999999999991

We shall use 113 bits of precision.
You seem to have entered 9999999999999991
Where mpfr_set_str() seems to see 9999999999999992.000000
nix$

Weird.

What am I missing ?


--
Dennis Clarke
RISC-V/SPARC/PPC/ARM/CISC
UNIX and Linux spoken
GreyBeard and suspenders optional
_______________________________________________
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs

Reply via email to