void check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v) { if (! refmpf_validate_division ("mpf_div", got, u, v)) { mp_trace_base = -16; mpf_trace (" u", u); mpf_trace (" v", v); printf (" %s\n", desc); abort (); } }
void check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want) { mp_trace_base = 16; mpf_trace ("src ", src); mpf_trace ("got ", got); mpf_trace ("want", want); printf ("got size=%d exp=%ld\n", SIZ(got), EXP(got)); mpn_trace (" limbs=", PTR(got), (mp_size_t) ABSIZ(got)); printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want)); mpn_trace (" limbs=", PTR(want), (mp_size_t) ABSIZ(want)); }
void check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpir_ui v) { mp_size_t usize, usign; mp_ptr wp; mpf_t want; MPF_CHECK_FORMAT (got); /* this code not nailified yet */ ASSERT_ALWAYS (BITS_PER_UI <= GMP_NUMB_BITS); usign = SIZ (u); usize = ABS (usign); wp = refmpn_malloc_limbs (usize + 1); wp[usize] = mpn_mul_1 (wp, PTR(u), usize, (mp_limb_t) v); PTR(want) = wp; SIZ(want) = (usign >= 0 ? usize+1 : -(usize+1)); EXP(want) = EXP(u) + 1; refmpf_normalize (want); if (! refmpf_validate ("mpf_mul_ui", got, want)) { mp_trace_base = -16; printf (" %s\n", desc); mpf_trace (" u", u); printf (" v %ld 0x%lX\n", v, v); abort (); } free (wp); }
void one (mpf_srcptr f, int want) { int got; got = mpf_integer_p (f); if (got != want) { printf ("mpf_integer_p got %d want %d\n", got, want); mpf_trace (" f", f); abort (); } }
void check_various (void) { mpf_t u, got, want; char *s; mpf_init2 (u, 2*8*sizeof(long)); mpf_init2 (got, 2*8*sizeof(long)); mpf_init2 (want, 2*8*sizeof(long)); s = "0 * GMP_UI_MAX"; mpf_set_ui (u, 0L); mpf_mul_ui (got, u, GMP_UI_MAX); MPF_CHECK_FORMAT (got); mpf_set_ui (want, 0L); if (mpf_cmp (got, want) != 0) { error: printf ("Wrong result from %s\n", s); mpf_trace ("u ", u); mpf_trace ("got ", got); mpf_trace ("want", want); abort (); } s = "1 * GMP_UI_MAX"; mpf_set_ui (u, 1L); mpf_mul_ui (got, u, GMP_UI_MAX); MPF_CHECK_FORMAT (got); mpf_set_ui (want, GMP_UI_MAX); if (mpf_cmp (got, want) != 0) goto error; mpf_clear (u); mpf_clear (got); mpf_clear (want); }
void check_one (const char *name, mpf_srcptr x, double y, int cmp) { int got; got = mpf_cmp_d (x, y); if (SGN(got) != cmp) { int i; printf ("mpf_cmp_d wrong (from %s)\n", name); printf (" got %d\n", got); printf (" want %d\n", cmp); mpf_trace (" x", x); printf (" y %g\n", y); mp_trace_base=-16; mpf_trace (" x", x); printf (" y %g\n", y); printf (" y"); for (i = 0; i < sizeof(y); i++) printf (" %02X", (unsigned) ((unsigned char *) &y)[i]); printf ("\n"); abort (); } }
void check_f (void) { static const struct { const char *fmt; const char *input; const char *want; int ret; long ftell; /* or -1 for length of input string */ } data[] = { { "%Ff", "0", "0", 1, -1 }, { "%Fe", "0", "0", 1, -1 }, { "%FE", "0", "0", 1, -1 }, { "%Fg", "0", "0", 1, -1 }, { "%FG", "0", "0", 1, -1 }, { "%Ff", "123", "123", 1, -1 }, { "%Ff", "+123", "123", 1, -1 }, { "%Ff", "-123", "-123", 1, -1 }, { "%Ff", "123.", "123", 1, -1 }, { "%Ff", "+123.", "123", 1, -1 }, { "%Ff", "-123.", "-123", 1, -1 }, { "%Ff", "123.0", "123", 1, -1 }, { "%Ff", "+123.0", "123", 1, -1 }, { "%Ff", "-123.0", "-123", 1, -1 }, { "%Ff", "0123", "123", 1, -1 }, { "%Ff", "-0123", "-123", 1, -1 }, { "%Ff", "123.456e3", "123456", 1, -1 }, { "%Ff", "-123.456e3", "-123456", 1, -1 }, { "%Ff", "123.456e+3", "123456", 1, -1 }, { "%Ff", "-123.456e+3", "-123456", 1, -1 }, { "%Ff", "123000e-3", "123", 1, -1 }, { "%Ff", "-123000e-3", "-123", 1, -1 }, { "%Ff", "123000.e-3", "123", 1, -1 }, { "%Ff", "-123000.e-3", "-123", 1, -1 }, { "%Ff", "123.456E3", "123456", 1, -1 }, { "%Ff", "-123.456E3", "-123456", 1, -1 }, { "%Ff", "123.456E+3", "123456", 1, -1 }, { "%Ff", "-123.456E+3", "-123456", 1, -1 }, { "%Ff", "123000E-3", "123", 1, -1 }, { "%Ff", "-123000E-3", "-123", 1, -1 }, { "%Ff", "123000.E-3", "123", 1, -1 }, { "%Ff", "-123000.E-3", "-123", 1, -1 }, { "%Ff", ".456e3", "456", 1, -1 }, { "%Ff", "-.456e3", "-456", 1, -1 }, { "%Ff", ".456e+3", "456", 1, -1 }, { "%Ff", "-.456e+3", "-456", 1, -1 }, { "%Ff", " 0", "0", 1, -1 }, { "%Ff", " 0", "0", 1, -1 }, { "%Ff", " 0", "0", 1, -1 }, { "%Ff", "\t0", "0", 1, -1 }, { "%Ff", "\t\t0", "0", 1, -1 }, { "hello%Fg", "hello0", "0", 1, -1 }, { "hello%Fg", "hello 0", "0", 1, -1 }, { "hello%Fg", "hello \t0", "0", 1, -1 }, { "hello%Fgworld", "hello 0world", "0", 1, -1 }, { "hello%Fg", "hello3.0", "3.0", 1, -1 }, { "hello%*Fg", "hello0", "-999", 0, -1 }, { "hello%*Fg", "hello 0", "-999", 0, -1 }, { "hello%*Fg", "hello \t0", "-999", 0, -1 }, { "hello%*Fgworld", "hello 0world", "-999", 0, -1 }, { "hello%*Fgworld", "hello3.0world", "-999", 0, -1 }, { "%Ff", "", "-999", -1, -1 }, { "%Ff", " ", "-999", -1, -1 }, { "%Ff", "\t", "-999", -1, -1 }, { "%Ff", " \t", "-999", -1, -1 }, { " %Ff", "", "-999", -1, -1 }, { "xyz%Ff", "", "-999", -1, -1 }, { "%*Ff", "", "-999", -1, -1 }, { " %*Ff", "", "-999", -1, -1 }, { "xyz%*Ff", "", "-999", -1, -1 }, { "%Ff", "xyz", "0", 0 }, /* various non-empty but invalid */ { "%Ff", "-", "-999", 0, 1 }, { "%Ff", "+", "-999", 0, 1 }, { "xyz%Ff", "xyz-", "-999", 0, 4 }, { "xyz%Ff", "xyz+", "-999", 0, 4 }, { "%Ff", "-.", "-999", 0, 2 }, { "%Ff", "+.", "-999", 0, 2 }, { "%Ff", ".e", "-999", 0, 1 }, { "%Ff", "-.e", "-999", 0, 2 }, { "%Ff", "+.e", "-999", 0, 2 }, { "%Ff", ".E", "-999", 0, 1 }, { "%Ff", "-.E", "-999", 0, 2 }, { "%Ff", "+.E", "-999", 0, 2 }, { "%Ff", ".e123", "-999", 0, 1 }, { "%Ff", "-.e123", "-999", 0, 2 }, { "%Ff", "+.e123", "-999", 0, 2 }, { "%Ff", "123e", "-999", 0, 4 }, { "%Ff", "-123e", "-999", 0, 5 }, { "%Ff", "123e-", "-999", 0, 5 }, { "%Ff", "-123e-", "-999", 0, 6 }, { "%Ff", "123e+", "-999", 0, 5 }, { "%Ff", "-123e+", "-999", 0, 6 }, { "%Ff", "123e-Z", "-999", 0, 5 }, /* hex floats */ { "%Ff", "0x123p0", "291", 1, -1 }, { "%Ff", "0x123P0", "291", 1, -1 }, { "%Ff", "0X123p0", "291", 1, -1 }, { "%Ff", "0X123P0", "291", 1, -1 }, { "%Ff", "-0x123p0", "-291", 1, -1 }, { "%Ff", "+0x123p0", "291", 1, -1 }, { "%Ff", "0x123.p0", "291", 1, -1 }, { "%Ff", "0x12.3p4", "291", 1, -1 }, { "%Ff", "-0x12.3p4", "-291", 1, -1 }, { "%Ff", "+0x12.3p4", "291", 1, -1 }, { "%Ff", "0x1230p-4", "291", 1, -1 }, { "%Ff", "-0x1230p-4", "-291", 1, -1 }, { "%Ff", "+0x1230p-4", "291", 1, -1 }, { "%Ff", "+0x.1230p12", "291", 1, -1 }, { "%Ff", "+0x123000p-12", "291", 1, -1 }, { "%Ff", "0x123 p12", "291", 1, 5 }, { "%Ff", "0x9 9", "9", 1, 3 }, { "%Ff", "0x01", "1", 1, 4 }, { "%Ff", "0x23", "35", 1, 4 }, { "%Ff", "0x45", "69", 1, 4 }, { "%Ff", "0x67", "103", 1, 4 }, { "%Ff", "0x89", "137", 1, 4 }, { "%Ff", "0xAB", "171", 1, 4 }, { "%Ff", "0xCD", "205", 1, 4 }, { "%Ff", "0xEF", "239", 1, 4 }, { "%Ff", "0xab", "171", 1, 4 }, { "%Ff", "0xcd", "205", 1, 4 }, { "%Ff", "0xef", "239", 1, 4 }, { "%Ff", "0x100p0A", "256", 1, 7 }, { "%Ff", "0x1p9", "512", 1, -1 }, /* invalid hex floats */ { "%Ff", "0x", "-999", 0, 2 }, { "%Ff", "-0x", "-999", 0, 3 }, { "%Ff", "+0x", "-999", 0, 3 }, { "%Ff", "0x-", "-999", 0, 2 }, { "%Ff", "0x+", "-999", 0, 2 }, { "%Ff", "0x.", "-999", 0, 3 }, { "%Ff", "-0x.", "-999", 0, 4 }, { "%Ff", "+0x.", "-999", 0, 4 }, { "%Ff", "0x.p", "-999", 0, 3 }, { "%Ff", "-0x.p", "-999", 0, 4 }, { "%Ff", "+0x.p", "-999", 0, 4 }, { "%Ff", "0x.P", "-999", 0, 3 }, { "%Ff", "-0x.P", "-999", 0, 4 }, { "%Ff", "+0x.P", "-999", 0, 4 }, { "%Ff", ".p123", "-999", 0, 1 }, { "%Ff", "-.p123", "-999", 0, 2 }, { "%Ff", "+.p123", "-999", 0, 2 }, { "%Ff", "0x1p", "-999", 0, 4 }, { "%Ff", "0x1p-", "-999", 0, 5 }, { "%Ff", "0x1p+", "-999", 0, 5 }, { "%Ff", "0x123p 12", "291", 0, 6 }, { "%Ff", "0x 123p12", "291", 0, 2 }, }; int i, j, ignore, got_ret, want_ret, got_upto, want_upto; mpf_t got, want; double got_d; long want_ftell; int error = 0; fun_t fun; const char *name; char fmt[128]; mpf_init (got); mpf_init (want); for (i = 0; i < numberof (data); i++) { mpf_set_str_or_abort (want, data[i].want, 10); ASSERT_ALWAYS (strlen (data[i].fmt) + 2 < sizeof (fmt)); strcpy (fmt, data[i].fmt); strcat (fmt, "%n"); ignore = (strchr (fmt, '*') != NULL); for (j = 0; j <= 3; j++) { want_ret = data[i].ret; want_ftell = data[i].ftell; if (want_ftell == -1) want_ftell = strlen (data[i].input); want_upto = want_ftell; if (want_ret == -1 || (want_ret == 0 && ! ignore)) want_upto = -555; switch (j) { case 0: name = "gmp_sscanf"; fun = fun_gmp_sscanf; break; case 1: name = "gmp_fscanf"; fun = fun_gmp_fscanf; break; case 2: if (! libc_scanf_convert (fmt)) continue; name = "standard sscanf"; fun = fun_sscanf; break; case 3: if (! libc_scanf_convert (fmt)) continue; name = "standard fscanf"; fun = fun_fscanf; break; default: ASSERT_ALWAYS (0); break; } got_upto = -555; got_ftell = -1; switch (j) { case 0: case 1: mpf_set_si (got, -999L); if (ignore) got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL); else got_ret = (*fun) (data[i].input, fmt, got, &got_upto); break; case 2: case 3: got_d = -999L; if (ignore) got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL); else got_ret = (*fun) (data[i].input, fmt, &got_d, &got_upto); mpf_set_d (got, got_d); break; default: ASSERT_ALWAYS (0); break; } MPF_CHECK_FORMAT (got); if (got_ret != want_ret) { printf ("%s wrong return value\n", name); error = 1; } if (want_ret == 1 && mpf_cmp (want, got) != 0) { printf ("%s wrong result\n", name); error = 1; } if (got_upto != want_upto) { printf ("%s wrong upto\n", name); error = 1; } if (got_ftell != -1 && want_ftell != -1 && got_ftell != want_ftell) { printf ("%s wrong ftell\n", name); error = 1; } if (error) { printf (" fmt \"%s\"\n", data[i].fmt); printf (" input \"%s\"\n", data[i].input); printf (" ret want=%d\n", want_ret); printf (" got =%d\n", got_ret); mpf_trace (" value want", want); mpf_trace (" got ", got); printf (" upto want=%d\n", want_upto); printf (" got =%d\n", got_upto); if (got_ftell != -1) { printf (" ftell want =%ld\n", want_ftell); printf (" got =%ld\n", got_ftell); } abort (); } } } mpf_clear (got); mpf_clear (want); }
void check_rand (void) { unsigned long max_prec = 15; unsigned long min_prec = __GMPF_BITS_TO_PREC (1); gmp_randstate_ptr rands = RANDS; unsigned long x, prec; mpf_t r, s; int i; mpf_init (r); mpf_init (s); refmpf_set_prec_limbs (s, 2*max_prec+10); for (i = 0; i < 50; i++) { /* input, a random non-zero ulong, exponentially distributed */ do { x = gmp_urandomb_ui (rands, gmp_urandomm_ui (rands, BITS_PER_ULONG) + 1); } while (x == 0); /* result precision */ prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec; refmpf_set_prec_limbs (r, prec); mpf_sqrt_ui (r, x); MPF_CHECK_FORMAT (r); /* Expect to prec limbs of result. In the current implementation there's no stripping of low zero limbs in mpf_sqrt_ui, not even on perfect squares, so size should be exactly prec. */ if (SIZ(r) != prec) { printf ("mpf_sqrt_ui result not enough result limbs\n"); printf (" x=%lu\n", x); printf (" want prec=%lu\n", prec); mpf_trace (" r", r); printf (" r size %ld\n", (long) SIZ(r)); printf (" r prec %ld\n", (long) PREC(r)); abort (); } /* Must have r^2 <= x, since r has been truncated. */ mpf_mul (s, r, r); if (! (mpf_cmp_ui (s, x) <= 0)) { printf ("mpf_sqrt_ui result too big\n"); printf (" x=%lu\n", x); printf (" want prec=%lu\n", prec); mpf_trace (" r", r); mpf_trace (" s", s); abort (); } /* Must have (r+ulp)^2 > x. No overflow from refmpf_add_ulp since r is only prec limbs. */ refmpf_add_ulp (r); mpf_mul (s, r, r); if (! (mpf_cmp_ui (s, x) > 0)) { printf ("mpf_sqrt_ui result too small\n"); printf (" x=%lu\n", x); printf (" want prec=%lu\n", prec); mpf_trace (" r+ulp", r); mpf_trace (" s", s); abort (); } } mpf_clear (r); mpf_clear (s); }
void check_limbdata (void) { #define M GMP_NUMB_MAX static const struct { mp_exp_t exp; mp_size_t size; mp_limb_t d[10]; unsigned long want; } data[] = { /* in the comments here, a "_" indicates a digit (ie. limb) position not included in the d data, and therefore zero */ { 0, 0, { 0 }, 0L }, /* 0 */ { 1, 1, { 1 }, 1L }, /* 1 */ { 1, -1, { 1 }, -1L }, /* -1 */ { 0, 1, { 1 }, 0L }, /* .1 */ { 0, -1, { 1 }, 0L }, /* -.1 */ { -1, 1, { 1 }, 0L }, /* ._1 */ { -1, -1, { 1 }, 0L }, /* -._1 */ { -999, 1, { 1 }, 0L }, /* .___1 small */ { MP_EXP_T_MIN, 1, { 1 }, 0L }, /* .____1 very small */ { 999, 1, { 1 }, 0L }, /* 1____. big */ { MP_EXP_T_MAX, 1, { 1 }, 0L }, /* 1_____. very big */ { 1, 2, { 999, 2 }, 2L }, /* 2.9 */ { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L }, /* 10003.987 */ { 2, 2, { M, M }, LONG_MAX }, /* FF. */ { 2, 2, { M, M, M }, LONG_MAX }, /* FF.F */ { 3, 3, { M, M, M }, LONG_MAX }, /* FFF. */ #if GMP_NUMB_BITS >= BITS_PER_ULONG /* normal case, numb bigger than long */ { 2, 1, { 1 }, 0L }, /* 1_. */ { 2, 2, { 0, 1 }, 0L }, /* 10. */ { 2, 2, { 999, 1 }, 999L }, /* 19. */ { 3, 2, { 999, 1 }, 0L }, /* 19_. */ #else /* nails case, numb smaller than long */ { 2, 1, { 1 }, 1L << GMP_NUMB_BITS }, /* 1_. */ { 3, 1, { 1 }, 0L }, /* 1__. */ { 2, 2, { 99, 1 }, 99L + (1L << GMP_NUMB_BITS) }, /* 19. */ { 3, 2, { 1, 99 }, 1L << GMP_NUMB_BITS }, /* 91_. */ { 3, 3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS }, /* 910. */ #endif }; mpf_t f; unsigned long got; int i; mp_limb_t buf[20 + numberof(data[i].d)]; for (i = 0; i < numberof (data); i++) { refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF)); refmpn_copy (buf+10, data[i].d, ABS(data[i].size)); refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF)); PTR(f) = buf+10; EXP(f) = data[i].exp; SIZ(f) = data[i].size; PREC(f) = numberof (data[i].d); MPF_CHECK_FORMAT (f); got = mpf_get_si (f); if (got != data[i].want) { printf ("mpf_get_si wrong at limb data[%d]\n", i); mpf_trace (" f", f); mpn_trace (" d", data[i].d, data[i].size); printf (" size %ld\n", (long) data[i].size); printf (" exp %ld\n", (long) data[i].exp); printf (" got %lu (0x%lX)\n", got, got); printf (" want %lu (0x%lX)\n", data[i].want, data[i].want); abort(); } } }
void check_one (mpz_srcptr z) { static const int shift[] = { 0, 1, BITS_PER_MP_LIMB, 2*BITS_PER_MP_LIMB, 5*BITS_PER_MP_LIMB }; int sh, shneg, neg; mpf_t f; mpz_t got, want; mpf_init2 (f, mpz_sizeinbase(z,2)); mpz_init (got); mpz_init (want); for (sh = 0; sh < numberof(shift); sh++) { for (shneg = 0; shneg <= 1; shneg++) { for (neg = 0; neg <= 1; neg++) { mpf_set_z (f, z); mpz_set (want, z); if (neg) { mpf_neg (f, f); mpz_neg (want, want); } if (shneg) { mpz_tdiv_q_2exp (want, want, shift[sh]); mpf_div_2exp (f, f, shift[sh]); } else { mpz_mul_2exp (want, want, shift[sh]); mpf_mul_2exp (f, f, shift[sh]); } mpz_set_f (got, f); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("wrong result\n"); printf (" shift %d\n", shneg ? -shift[sh] : shift[sh]); printf (" neg %d\n", neg); mpf_trace (" f", f); mpz_trace (" got", got); mpz_trace (" want", want); abort (); } } } } mpf_clear (f); mpz_clear (got); mpz_clear (want); }
void check_data (void) { static const struct { struct { int exp, size; mp_limb_t d[10]; } x, y, want; } data[] = { { { 123, 2, { 8, 9 } }, { 123, 1, { 9 } }, { 122, 1, { 8 } } }, /* f - f == 0, various sizes. These exercise a past problem (gmp 4.1.3 and earlier) where the result exponent was not zeroed on a zero result like this. */ { { 0, 0 }, { 0, 0 }, { 0, 0 } }, { { 99, 1, { 1 } }, { 99, 1, { 1 } }, { 0, 0 } }, { { 99, 2, { 123, 456 } }, { 99, 2, { 123, 456 } }, { 0, 0 } }, { { 99, 3, { 123, 456, 789 } }, { 99, 3, { 123, 456, 789 } }, { 0, 0 } }, /* High limbs cancel, leaving just the low limbs of the longer operand. This exercises a past problem (gmp 4.1.3 and earlier) where high zero limbs on the remainder were not stripped before truncating to the destination, causing loss of precision. */ { { 123, 2, { 8, 9 } }, { 123, 1, { 9 } }, { 122, 1, { 8 } } }, { { 123, 3, { 8, 0, 9 } }, { 123, 1, { 9 } }, { 121, 1, { 8 } } }, { { 123, 4, { 8, 0, 0, 9 } }, { 123, 1, { 9 } }, { 120, 1, { 8 } } }, { { 123, 5, { 8, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 119, 1, { 8 } } }, { { 123, 6, { 8, 0, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 118, 1, { 8 } } }, }; mpf_t x, y, got, want; int i, swap; mp_trace_base = 16; mpf_init (got); for (i = 0; i < numberof (data); i++) { for (swap = 0; swap <= 1; swap++) { PTR(x) = (mp_ptr) data[i].x.d; SIZ(x) = data[i].x.size; EXP(x) = data[i].x.exp; PREC(x) = numberof (data[i].x.d); MPF_CHECK_FORMAT (x); PTR(y) = (mp_ptr) data[i].y.d; SIZ(y) = data[i].y.size; EXP(y) = data[i].y.exp; PREC(y) = numberof (data[i].y.d); MPF_CHECK_FORMAT (y); PTR(want) = (mp_ptr) data[i].want.d; SIZ(want) = data[i].want.size; EXP(want) = data[i].want.exp; PREC(want) = numberof (data[i].want.d); MPF_CHECK_FORMAT (want); if (swap) { mpf_swap (x, y); SIZ(want) = - SIZ(want); } mpf_sub (got, x, y); /* MPF_CHECK_FORMAT (got); */ if (mpf_cmp (got, want) != 0) { printf ("check_data() wrong reault at data[%d] (operands%s swapped)\n", i, swap ? "" : " not"); mpf_trace ("x ", x); mpf_trace ("y ", y); mpf_trace ("got ", got); mpf_trace ("want", want); abort (); } } } mpf_clear (got); }
void check_rand1 (int argc, char **argv) { mp_size_t size; mp_exp_t exp; int reps = 20000; int i; mpf_t x, y, y2; mp_size_t bprec = 100; mpf_t rerr, max_rerr, limit_rerr; if (argc > 1) { reps = strtol (argv[1], 0, 0); if (argc > 2) bprec = strtol (argv[2], 0, 0); } mpf_set_default_prec (bprec); mpf_init_set_ui (limit_rerr, 1); mpf_div_2exp (limit_rerr, limit_rerr, bprec); #if VERBOSE mpf_dump (limit_rerr); #endif mpf_init (rerr); mpf_init_set_ui (max_rerr, 0); mpf_init (x); mpf_init (y); mpf_init (y2); for (i = 0; i < reps; i++) { size = urandom () % SIZE; exp = urandom () % SIZE; mpf_random2 (x, size, exp); mpf_sqrt (y, x); MPF_CHECK_FORMAT (y); mpf_mul (y2, y, y); mpf_reldiff (rerr, x, y2); if (mpf_cmp (rerr, max_rerr) > 0) { mpf_set (max_rerr, rerr); #if VERBOSE mpf_dump (max_rerr); #endif if (mpf_cmp (rerr, limit_rerr) > 0) { printf ("ERROR after %d tests\n", i); printf (" x = "); mpf_dump (x); printf (" y = "); mpf_dump (y); printf (" y2 = "); mpf_dump (y2); printf (" rerr = "); mpf_dump (rerr); printf (" limit_rerr = "); mpf_dump (limit_rerr); printf ("in hex:\n"); mp_trace_base = 16; mpf_trace (" x ", x); mpf_trace (" y ", y); mpf_trace (" y2 ", y2); mpf_trace (" rerr ", rerr); mpf_trace (" limit_rerr", limit_rerr); abort (); } } } mpf_clear (limit_rerr); mpf_clear (rerr); mpf_clear (max_rerr); mpf_clear (x); mpf_clear (y); mpf_clear (y2); }
void check_rand2 (void) { unsigned long max_prec = 20; unsigned long min_prec = __GMPF_BITS_TO_PREC (1); gmp_randstate_ptr rands = RANDS; unsigned long x_prec, r_prec; mpf_t x, r, s; int i; mpf_init (x); mpf_init (r); mpf_init (s); refmpf_set_prec_limbs (s, 2*max_prec+10); for (i = 0; i < 500; i++) { /* input precision */ x_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec; refmpf_set_prec_limbs (x, x_prec); /* result precision */ r_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec; refmpf_set_prec_limbs (r, r_prec); mpf_random2 (x, x_prec, 1000); mpf_sqrt (r, x); MPF_CHECK_FORMAT (r); /* Expect to prec limbs of result. In the current implementation there's no stripping of low zero limbs in mpf_sqrt, so size should be exactly prec. */ if (SIZ(r) != r_prec) { printf ("mpf_sqrt wrong number of result limbs\n"); mpf_trace (" x", x); mpf_trace (" r", r); printf (" r_prec=%lu\n", r_prec); printf (" SIZ(r) %ld\n", (long) SIZ(r)); printf (" PREC(r) %ld\n", (long) PREC(r)); abort (); } /* Must have r^2 <= x, since r has been truncated. */ mpf_mul (s, r, r); if (! (mpf_cmp (s, x) <= 0)) { printf ("mpf_sqrt result too big\n"); mpf_trace (" x", x); printf (" r_prec=%lu\n", r_prec); mpf_trace (" r", r); mpf_trace (" s", s); abort (); } /* Must have (r+ulp)^2 > x, or else r is too small. */ refmpf_add_ulp (r); mpf_mul (s, r, r); if (! (mpf_cmp (s, x) > 0)) { printf ("mpf_sqrt result too small\n"); mpf_trace (" x", x); printf (" r_prec=%lu\n", r_prec); mpf_trace (" r+ulp", r); mpf_trace (" s", s); abort (); } } mpf_clear (x); mpf_clear (r); mpf_clear (s); }
void check_data (void) { static const struct { struct { int exp, size; mp_limb_t d[10]; } x, y; mp_bitcnt_t bits; int want; } data[] = { { { 0, 0, { 0 } }, { 0, 0, { 0 } }, 0, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 0, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 17, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 4711, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 0, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 2, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 3, 0 }, { { 0, 0, { 0 } }, { 0, 1, { 1 } }, 0, 0 }, { { 0, 1, { 1 } }, { 0,-1 ,{ 1 } }, 0, 0 }, { { 1, 1, { 1 } }, { 0, 1, { 1 } }, 0, 0 }, { { 0, 1, { 8 } }, { 0, 1, { 4 } }, 0, 0 }, { { 0, 2, { 0, 3 } }, { 0, 1, { 3 } }, 1000, 1 }, }; mpf_t x, y; int got, got_swapped; int i; mp_trace_base = 16; for (i = 0; i < numberof (data); i++) { PTR(x) = (mp_ptr) data[i].x.d; SIZ(x) = data[i].x.size; EXP(x) = data[i].x.exp; PREC(x) = numberof (data[i].x.d); MPF_CHECK_FORMAT (x); PTR(y) = (mp_ptr) data[i].y.d; SIZ(y) = data[i].y.size; EXP(y) = data[i].y.exp; PREC(y) = numberof (data[i].y.d); MPF_CHECK_FORMAT (y); got = mpf_eq (x, y, data[i].bits); got_swapped = mpf_eq (y, x, data[i].bits); if (got != got_swapped || got != data[i].want) { printf ("check_data() wrong result at data[%d]\n", i); mpf_trace ("x ", x); mpf_trace ("y ", y); printf ("got %d\n", got); printf ("got_swapped %d\n", got_swapped); printf ("want %d\n", data[i].want); abort (); } } }
void check_input (void) { static const char *point[] = { ".", ",", "WU", "STR", "ZTV***" }; static const struct { const char *str; double d; } data[] = { { "1%s", 1.0 }, { "1%s0", 1.0 }, { "1%s00", 1.0 }, { "%s5", 0.5 }, { "0%s5", 0.5 }, { "00%s5", 0.5 }, { "00%s50", 0.5 }, { "1%s5", 1.5 }, { "1%s5e1", 15.0 }, }; int i, j, neg, ret; char str[128]; mpf_t f; double d; mpf_init (f); for (i = 0; i < numberof (point); i++) { decimal_point = (const char *) point[i]; for (neg = 0; neg <= 1; neg++) { for (j = 0; j < numberof (data); j++) { strcpy (str, neg ? "-" : ""); sprintf (str+strlen(str), data[j].str, decimal_point); d = data[j].d; if (neg) d = -d; mpf_set_d (f, 123.0); if (mpf_set_str (f, str, 10) != 0) { printf ("mpf_set_str error\n"); printf (" point %s\n", decimal_point); printf (" str %s\n", str); abort (); } if (mpf_cmp_d (f, d) != 0) { printf ("mpf_set_str wrong result\n"); printf (" point %s\n", decimal_point); printf (" str %s\n", str); mpf_trace (" f", f); printf (" d=%g\n", d); abort (); } mpf_set_d (f, 123.0); ret = gmp_sscanf (str, "%Ff", f); if (ret != 1) { printf ("gmp_sscanf wrong return value\n"); printf (" point %s\n", decimal_point); printf (" str %s\n", str); printf (" ret %d\n", ret); abort (); } if (mpf_cmp_d (f, d) != 0) { printf ("gmp_sscanf wrong result\n"); printf (" point %s\n", decimal_point); printf (" str %s\n", str); mpf_trace (" f", f); printf (" d=%g\n", d); abort (); } } } } mpf_clear (f); }