int main (int argc, char *argv[]) { int i, N=10000, p; mpfr_rnd_t rnd; double d; tests_start_mpfr (); /* with no argument: prints to /dev/null, tout_str N: prints N tests to stdout */ if (argc == 1) { fout = fopen ("/dev/null", "w"); /* If we failed to open this device, try with a dummy file */ if (fout == NULL) fout = fopen ("mpfrtest.txt", "w"); } else { fout = stdout; N = atoi (argv[1]); } if (fout == NULL) { printf ("Can't open /dev/null or stdout\n"); exit (1); } special (); check (-1.37247529013405550000e+15, MPFR_RNDN, 7); check (-1.5674376729569697500e+15, MPFR_RNDN, 19); check (-5.71262771772792640000e-79, MPFR_RNDU, 16); check (DBL_NEG_ZERO, MPFR_RNDU, 7); check (-4.5306392613572974756e-308, MPFR_RNDN, 8); check (-6.7265890111403371523e-165, MPFR_RNDN, 4); check (-1.3242553591261807653e+156, MPFR_RNDN, 16); check (-6.606499965302424244461355e233, MPFR_RNDN, 10); check4 (1.0, MPFR_RNDN, 10, 120); check (1.0, MPFR_RNDU, 10); check (4.059650008e-83, MPFR_RNDN, 10); check (-7.4, MPFR_RNDN, 10); check (0.997, MPFR_RNDN, 10); check (-4.53063926135729747564e-308, MPFR_RNDN, 10); check (2.14478198760196000000e+16, MPFR_RNDN, 10); check (7.02293374921793516813e-84, MPFR_RNDN, 10); /* random tests */ for (i=0;i<N;i++) { do { d = DBL_RAND (); } #ifdef HAVE_DENORMS while (0); #else while (ABS(d) < DBL_MIN); #endif rnd = RND_RAND (); p = 2 + randlimb () % 61; check (d, rnd, p); } fclose (fout); tests_end_mpfr (); return 0; }
/* check concordance between mpfr_asprintf result with a regular mpfr float and with a regular double float */ static int random_double (void) { mpfr_t x; /* random regular mpfr float */ double y; /* regular double float (equal to x) */ char flag[] = { '-', '+', ' ', '#', '0', /* no ambiguity: first zeros are flag zero*/ '\'' }; /* no 'a': mpfr and glibc do not have the same semantic */ char specifier[] = { 'e', 'f', 'g', 'E', 'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for regular numbers */ 'G', }; int spec; /* random index in specifier[] */ int prec; /* random value for precision field */ /* in the format string for mpfr_t variable, the maximum length is reached by something like "%-+ #0'.*Rf", that is 12 characters. */ #define FMT_MPFR_SIZE 12 char fmt_mpfr[FMT_MPFR_SIZE]; char *ptr_mpfr; /* in the format string for double variable, the maximum length is reached by something like "%-+ #0'.*f", that is 11 characters. */ #define FMT_SIZE 11 char fmt[FMT_SIZE]; char *ptr; int xi; char *xs; int yi; char *ys; int i, j, jmax; mpfr_init2 (x, MPFR_LDBL_MANT_DIG); for (i = 0; i < 1000; ++i) { /* 1. random double */ do { y = DBL_RAND (); } #ifdef HAVE_DENORMS while (0); #else while (ABS(y) < DBL_MIN); #endif if (randlimb () % 2 == 0) y = -y; mpfr_set_d (x, y, MPFR_RNDN); if (y != mpfr_get_d (x, MPFR_RNDN)) /* conversion error: skip this one */ continue; /* 2. build random format strings fmt_mpfr and fmt */ ptr_mpfr = fmt_mpfr; ptr = fmt; *ptr_mpfr++ = *ptr++ = '%'; /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */ spec = (int) (randlimb() % 6); /* random flags, but no ' flag with %e */ jmax = (spec == 0 || spec == 3) ? 5 : 6; for (j = 0; j < jmax; j++) { if (randlimb() % 3 == 0) *ptr_mpfr++ = *ptr++ = flag[j]; } *ptr_mpfr++ = *ptr++ = '.'; *ptr_mpfr++ = *ptr++ = '*'; *ptr_mpfr++ = 'R'; *ptr_mpfr++ = *ptr++ = specifier[spec]; *ptr_mpfr = *ptr = '\0'; MPFR_ASSERTN (ptr - fmt < FMT_SIZE); MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE); /* advantage small precision */ if (randlimb() % 2 == 0) prec = (int) (randlimb() % 10); else prec = (int) (randlimb() % prec_max_printf); /* 3. calls and checks */ /* the double float case is handled by the libc asprintf through gmp_asprintf */ xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x); yi = mpfr_asprintf (&ys, fmt, prec, y); /* test if XS and YS differ, beware that ISO C99 doesn't specify the sign of a zero exponent (the C99 rationale says: "The sign of a zero exponent in %e format is unspecified. The committee knows of different implementations and choose not to require implementations to document their behaviour in this case (by making this be implementation defined behaviour). Most implementations use a "+" sign, e.g., 1.2e+00; but there is at least one implementation that uses the sign of the unlimited precision result, e.g., the 0.987 would be 9.87e-01, so could end up as 1e-00 after rounding to one digit of precision."), while mpfr always uses '+' */ if (xi != yi || ((strcmp (xs, ys) != 0) && (spec == 1 || spec == 4 || ((strstr (xs, "e+00") == NULL || strstr (ys, "e-00") == NULL) && (strstr (xs, "E+00") == NULL || strstr (ys, "E-00") == NULL))))) { mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n", fmt_mpfr, prec, x); printf ("expected: %s\n", ys); printf (" got: %s\n", xs); printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec); exit (1); } mpfr_free_str (xs); mpfr_free_str (ys); } mpfr_clear (x); return 0; }
int main (int argc, char *argv[]) { mpfr_t x, y, z; unsigned long k, n; volatile double d; double dd; tests_start_mpfr (); mpfr_test_init (); #ifndef MPFR_DOUBLE_SPEC printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n" "that you do not have a conforming C implementation and problems\n" "may occur with conversions between MPFR numbers and standard\n" "floating-point types. Please contact the MPFR team.\n"); #elif MPFR_DOUBLE_SPEC == 0 /* printf ("The type 'double' of your C implementation does not seem to\n" "correspond to the IEEE-754 double precision. Though code has\n" "been written to support such implementations, tests have been\n" "done only on IEEE-754 double-precision implementations and\n" "conversions between MPFR numbers and standard floating-point\n" "types may be inaccurate. You may wish to contact the MPFR team\n" "for further testing.\n"); */ printf ("The type 'double' of your C implementation does not seem to\n" "correspond to the IEEE-754 double precision. Such particular\n" "implementations are not supported yet, and conversions between\n" "MPFR numbers and standard floating-point types may be very\n" "inaccurate.\n"); printf ("FLT_RADIX = %ld\n", (long) FLT_RADIX); printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG); printf ("DBL_MIN_EXP = %ld\n", (long) DBL_MIN_EXP); printf ("DBL_MAX_EXP = %ld\n", (long) DBL_MAX_EXP); #endif mpfr_init (x); mpfr_set_nan (x); d = mpfr_get_d (x, GMP_RNDN); if (! DOUBLE_ISNAN (d)) { printf ("ERROR for NAN (1)\n"); #ifdef MPFR_NANISNAN printf ("The reason is that NAN == NAN. Please look at the configure " "output\nand Section \"In case of problem\" of the INSTALL " "file.\n"); #endif exit (1); } mpfr_set_ui (x, 0, GMP_RNDN); mpfr_set_d (x, d, GMP_RNDN); if (! mpfr_nan_p (x)) { printf ("ERROR for NAN (2)\n"); #ifdef MPFR_NANISNAN printf ("The reason is that NAN == NAN. Please look at the configure " "output\nand Section \"In case of problem\" of the INSTALL " "file.\n"); #endif exit (1); } d = 0.0; mpfr_set_d (x, d, GMP_RNDN); MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); d = -d; mpfr_set_d (x, d, GMP_RNDN); if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x)) { printf ("Error in mpfr_set_d on -0\n"); exit (1); } mpfr_set_inf (x, 1); d = mpfr_get_d (x, GMP_RNDN); mpfr_set_ui (x, 0, GMP_RNDN); mpfr_set_d (x, d, GMP_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); mpfr_set_inf (x, -1); d = mpfr_get_d (x, GMP_RNDN); mpfr_set_ui (x, 0, GMP_RNDN); mpfr_set_d (x, d, GMP_RNDN); MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); mpfr_set_prec (x, 2); /* checks that denormalized are not flushed to zero */ d = DBL_MIN; /* 2^(-1022) */ for (n=0; n<52; n++, d /= 2.0) if (d != 0.0) /* should be 2^(-1022-n) */ { mpfr_set_d (x, d, GMP_RNDN); if (mpfr_cmp_ui_2exp (x, 1, -1022-n)) { printf ("Wrong result for d=2^(%ld), ", -1022-n); printf ("got "); mpfr_out_str (stdout, 10, 10, x, GMP_RNDN); printf ("\n"); mpfr_print_binary (x); puts (""); exit (1); } } /* checks that rounds to nearest sets the last bit to zero in case of equal distance */ mpfr_set_d (x, 5.0, GMP_RNDN); if (mpfr_cmp_ui (x, 4)) { printf ("Error in tset_d: expected 4.0, got "); mpfr_print_binary (x); putchar('\n'); exit (1); } mpfr_set_d (x, -5.0, GMP_RNDN); if (mpfr_cmp_si (x, -4)) { printf ("Error in tset_d: expected -4.0, got "); mpfr_print_binary (x); putchar('\n'); exit (1); } mpfr_set_d (x, 9.84891017624509146344e-01, GMP_RNDU); if (mpfr_cmp_ui (x, 1)) { printf ("Error in tset_d: expected 1.0, got "); mpfr_print_binary (x); putchar('\n'); exit (1); } mpfr_init2 (z, 32); mpfr_set_d (z, 1.0, (mp_rnd_t) 0); if (mpfr_cmp_ui (z, 1)) { mpfr_print_binary (z); puts (""); printf ("Error: 1.0 != 1.0\n"); exit (1); } mpfr_set_prec (x, 53); mpfr_init2 (y, 53); mpfr_set_d (x, d=-1.08007920352320089721e+150, (mp_rnd_t) 0); if (mpfr_get_d1 (x) != d) { mpfr_print_binary (x); puts (""); printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n", d, mpfr_get_d1 (x)); exit (1); } mpfr_set_d (x, 8.06294740693074521573e-310, (mp_rnd_t) 0); d = -6.72658901114033715233e-165; mpfr_set_d (x, d, (mp_rnd_t) 0); if (d != mpfr_get_d1 (x)) { mpfr_print_binary (x); puts (""); printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n", d, mpfr_get_d1 (x)); exit (1); } n = (argc==1) ? 500000 : atoi(argv[1]); for (k = 1; k <= n; k++) { do { d = DBL_RAND (); } #ifdef HAVE_DENORMS while (0); #else while (ABS(d) < DBL_MIN); #endif mpfr_set_d (x, d, (mp_rnd_t) 0); dd = mpfr_get_d1 (x); if (d != dd && !(Isnan(d) && Isnan(dd))) { printf ("Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d1 (x)); mpfr_print_binary (x); puts (""); exit (1); } } mpfr_clear (x); mpfr_clear (y); mpfr_clear (z); tests_end_mpfr (); return 0; }
int main (void) { double x, y; mpfr_t xx, yy; int c; long i; mp_prec_t p; tests_start_mpfr (); mpfr_init (xx); mpfr_init (yy); mpfr_set_prec (xx, 2); mpfr_set_prec (yy, 2); mpfr_set_str_binary(xx, "-0.10E0"); mpfr_set_str_binary(yy, "-0.10E0"); if ((mpfr_cmp) (xx, yy)) { printf ("mpfr_cmp (xx, yy) returns non-zero for prec=2\n"); exit (1); } mpfr_set_prec (xx, 65); mpfr_set_prec (yy, 65); mpfr_set_str_binary(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623"); mpfr_set_str_binary(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); p = 0; if (mpfr_cmp2(xx, yy, &p) <= 0 || p != 64) { printf ("Error (1) in mpfr_cmp2\n"); exit (1); } mpfr_set_str_binary(xx, "0.10100010001110110111000010001000010011111101000100011101000011100"); mpfr_set_str_binary(yy, "0.10100010001110110111000010001000010011111101000100011101000011011"); p = 0; if (mpfr_cmp2(xx, yy, &p) <= 0 || p != 64) { printf ("Error (2) in mpfr_cmp2\n"); exit (1); } mpfr_set_prec (xx, 160); mpfr_set_prec (yy, 160); mpfr_set_str_binary (xx, "0.1E1"); mpfr_set_str_binary (yy, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100"); p = 0; if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 144) { printf ("Error (3) in mpfr_cmp2\n"); exit (1); } mpfr_set_prec (xx, 53); mpfr_set_prec (yy, 200); mpfr_set_ui (xx, 1, (mp_rnd_t) 0); mpfr_set_ui (yy, 1, (mp_rnd_t) 0); if (mpfr_cmp (xx, yy) != 0) { printf ("Error in mpfr_cmp: 1.0 != 1.0\n"); exit (1); } mpfr_set_prec (yy, 31); mpfr_set_str (xx, "1.0000000002", 10, (mp_rnd_t) 0); mpfr_set_ui (yy, 1, (mp_rnd_t) 0); if (!(mpfr_cmp (xx,yy)>0)) { printf ("Error in mpfr_cmp: not 1.0000000002 > 1.0\n"); exit (1); } mpfr_set_prec (yy, 53); /* bug found by Gerardo Ballabio */ mpfr_set_ui(xx, 0, GMP_RNDN); mpfr_set_str (yy, "0.1", 10, GMP_RNDN); if (mpfr_cmp(xx, yy) >= 0) { printf ("Error in mpfr_cmp(0.0, 0.1), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_inf (xx, 1); mpfr_set_str (yy, "-23489745.0329", 10, GMP_RNDN); if (mpfr_cmp(xx, yy) <= 0) { printf ("Error in mpfr_cmp(Infp, 23489745.0329), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_inf (xx, 1); mpfr_set_inf (yy, -1); if (mpfr_cmp(xx, yy) <= 0) { printf ("Error in mpfr_cmp(Infp, Infm), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_inf (xx, -1); mpfr_set_inf (yy, 1); if (mpfr_cmp(xx, yy) >= 0) { printf ("Error in mpfr_cmp(Infm, Infp), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_inf (xx, 1); mpfr_set_inf (yy, 1); if (mpfr_cmp(xx, yy) != 0) { printf ("Error in mpfr_cmp(Infp, Infp), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_inf (xx, -1); mpfr_set_inf (yy, -1); if (mpfr_cmp(xx, yy) != 0) { printf ("Error in mpfr_cmp(Infm, Infm), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_inf (xx, -1); mpfr_set_str (yy, "2346.09234", 10, GMP_RNDN); if (mpfr_cmp(xx, yy) >= 0) { printf ("Error in mpfr_cmp(Infm, 2346.09234), gives %d\n", mpfr_cmp(xx, yy)); exit (1); } mpfr_set_ui (xx, 0, GMP_RNDN); mpfr_set_ui (yy, 1, GMP_RNDN); if ((i = mpfr_cmp3 (xx, yy, 1)) >= 0) { printf ("Error: mpfr_cmp3 (0, 1, 1) gives %d instead of" " a negative value\n", i); exit (1); } if ((i = mpfr_cmp3 (xx, yy, -1)) <= 0) { printf ("Error: mpfr_cmp3 (0, 1, -1) gives %d instead of" " a positive value\n", i); exit (1); } for (i=0; i<500000; ) { x = DBL_RAND (); y = DBL_RAND (); if (!Isnan(x) && !Isnan(y)) { i++; mpfr_set_d (xx, x, GMP_RNDN); mpfr_set_d (yy, y, GMP_RNDN); c = mpfr_cmp (xx,yy); if ((c>0 && x<=y) || (c==0 && x!=y) || (c<0 && x>=y)) { printf ("Error in mpfr_cmp with x=%1.20e, y=%1.20e" " mpfr_cmp(x,y)=%d\n", x, y, c); exit (1); } } } /* Check for NAN */ mpfr_set_nan (xx); mpfr_clear_erangeflag (); c = (mpfr_cmp) (xx, yy); if (c != 0 || !mpfr_erangeflag_p () ) { printf ("NAN error (1)\n"); exit (1); } mpfr_clear_erangeflag (); c = (mpfr_cmp) (yy, xx); if (c != 0 || !mpfr_erangeflag_p () ) { printf ("NAN error (2)\n"); exit (1); } mpfr_clear_erangeflag (); c = (mpfr_cmp) (xx, xx); if (c != 0 || !mpfr_erangeflag_p () ) { printf ("NAN error (3)\n"); exit (1); } mpfr_clear (xx); mpfr_clear (yy); tests_end_mpfr (); return 0; }