void check_one (mpq_srcptr want, int base, const char *str) { mpq_t got; MPQ_CHECK_FORMAT (want); mp_trace_base = base; mpq_init (got); if (mpq_set_str (got, str, base) != 0) { printf ("mpq_set_str unexpectedly failed\n"); printf (" base %d\n", base); printf (" str \"%s\"\n", str); abort (); } MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want)) { printf ("mpq_set_str wrong\n"); printf (" base %d\n", base); printf (" str \"%s\"\n", str); mpq_trace ("got ", got); mpq_trace ("want", want); abort (); } mpq_clear (got); }
void check_one (mpq_srcptr x, mpq_srcptr y, int want) { int got; MPQ_CHECK_FORMAT (x); MPQ_CHECK_FORMAT (y); got = mpq_equal (x, y); if ((got != 0) != (want != 0)) { printf ("mpq_equal got %d want %d\n", got, want); mpq_trace ("x", x); mpq_trace ("y", y); abort (); } }
void check_one (mpq_srcptr q, int base, const char *want) { char *str, *ret; size_t str_alloc; MPQ_CHECK_FORMAT (q); mp_trace_base = base; str_alloc = mpz_sizeinbase (mpq_numref(q), ABS(base)) + mpz_sizeinbase (mpq_denref(q), ABS(base)) + 3; str = mpq_get_str (NULL, base, q); if (strlen(str)+1 > str_alloc) { printf ("mpq_get_str size bigger than should be (passing NULL)\n"); printf (" base %d\n", base); printf (" got size %lu \"%s\"\n", (unsigned long) strlen(str)+1, str); printf (" want size %lu\n", (unsigned long) str_alloc); abort (); } if (strcmp (str, want) != 0) { printf ("mpq_get_str wrong (passing NULL)\n"); printf (" base %d\n", base); printf (" got \"%s\"\n", str); printf (" want \"%s\"\n", want); mpq_trace (" q", q); abort (); } (*__gmp_free_func) (str, strlen (str) + 1); str = (char *) (*__gmp_allocate_func) (str_alloc); ret = mpq_get_str (str, base, q); if (str != ret) { printf ("mpq_get_str wrong return value (passing non-NULL)\n"); printf (" base %d\n", base); printf (" got %p\n", ret); printf (" want %p\n", want); abort (); } if (strcmp (str, want) != 0) { printf ("mpq_get_str wrong (passing non-NULL)\n"); printf (" base %d\n", base); printf (" got \"%s\"\n", str); printf (" want \"%s\"\n", want); abort (); } (*__gmp_free_func) (str, str_alloc); }
void check_all (mpq_ptr x, mpq_ptr y, mpq_ptr want_add, mpq_ptr want_sub) { mpq_t got; int neg_x, neg_y, swap; mpq_init (got); MPQ_CHECK_FORMAT (want_add); MPQ_CHECK_FORMAT (want_sub); MPQ_CHECK_FORMAT (x); MPQ_CHECK_FORMAT (y); for (swap = 0; swap <= 1; swap++) { for (neg_x = 0; neg_x <= 1; neg_x++) { for (neg_y = 0; neg_y <= 1; neg_y++) { mpq_add (got, x, y); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want_add)) { printf ("mpq_add wrong\n"); mpq_trace (" x ", x); mpq_trace (" y ", y); mpq_trace (" got ", got); mpq_trace (" want", want_add); abort (); } mpq_sub (got, x, y); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want_sub)) { printf ("mpq_sub wrong\n"); mpq_trace (" x ", x); mpq_trace (" y ", y); mpq_trace (" got ", got); mpq_trace (" want", want_sub); abort (); } mpq_neg (y, y); mpq_swap (want_add, want_sub); } mpq_neg (x, x); mpq_swap (want_add, want_sub); mpq_neg (want_add, want_add); mpq_neg (want_sub, want_sub); } mpq_swap (x, y); mpq_neg (want_sub, want_sub); } mpq_clear (got); }
void check_n (void) { int ret; /* %n suppressed */ { int n = 123; gmp_sscanf (" ", " %*n", &n); ASSERT_ALWAYS (n == 123); } { int n = 123; fromstring_gmp_fscanf (" ", " %*n", &n); ASSERT_ALWAYS (n == 123); } #define CHECK_N(type, string) \ do { \ type x[2]; \ char fmt[128]; \ int ret; \ \ x[0] = ~ (type) 0; \ x[1] = ~ (type) 0; \ sprintf (fmt, "abc%%%sn", string); \ ret = gmp_sscanf ("abc", fmt, &x[0]); \ \ ASSERT_ALWAYS (ret == 0); \ \ /* should write whole of x[0] and none of x[1] */ \ ASSERT_ALWAYS (x[0] == 3); \ ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \ \ } while (0) CHECK_N (char, "hh"); CHECK_N (long, "l"); #if HAVE_LONG_LONG CHECK_N (long long, "L"); #endif #if HAVE_INTMAX_T CHECK_N (intmax_t, "j"); #endif #if HAVE_PTRDIFF_T CHECK_N (ptrdiff_t, "t"); #endif CHECK_N (short, "h"); CHECK_N (size_t, "z"); /* %Zn */ { mpz_t x[2]; mpz_init_set_si (x[0], -987L); mpz_init_set_si (x[1], 654L); ret = gmp_sscanf ("xyz ", "xyz%Zn", x[0]); MPZ_CHECK_FORMAT (x[0]); MPZ_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (ret == 0); ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0); ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0); mpz_clear (x[0]); mpz_clear (x[1]); } { mpz_t x; mpz_init (x); ret = fromstring_gmp_fscanf ("xyz ", "xyz%Zn", x); ASSERT_ALWAYS (ret == 0); ASSERT_ALWAYS (mpz_cmp_ui (x, 3L) == 0); mpz_clear (x); } /* %Qn */ { mpq_t x[2]; mpq_init (x[0]); mpq_init (x[1]); mpq_set_ui (x[0], -987L, 654L); mpq_set_ui (x[1], 4115L, 226L); ret = gmp_sscanf ("xyz ", "xyz%Qn", x[0]); MPQ_CHECK_FORMAT (x[0]); MPQ_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (ret == 0); ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0); ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0); mpq_clear (x[0]); mpq_clear (x[1]); } { mpq_t x; mpq_init (x); ret = fromstring_gmp_fscanf ("xyz ", "xyz%Qn", x); ASSERT_ALWAYS (ret == 0); ASSERT_ALWAYS (mpq_cmp_ui (x, 3L, 1L) == 0); mpq_clear (x); } /* %Fn */ { mpf_t x[2]; mpf_init (x[0]); mpf_init (x[1]); mpf_set_ui (x[0], -987L); mpf_set_ui (x[1], 654L); ret = gmp_sscanf ("xyz ", "xyz%Fn", x[0]); MPF_CHECK_FORMAT (x[0]); MPF_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (ret == 0); ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0); ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0); mpf_clear (x[0]); mpf_clear (x[1]); } { mpf_t x; mpf_init (x); ret = fromstring_gmp_fscanf ("xyz ", "xyz%Fn", x); ASSERT_ALWAYS (ret == 0); ASSERT_ALWAYS (mpf_cmp_ui (x, 3L) == 0); mpf_clear (x); } }
int main (int argc, char **argv) { #if GMP_NAIL_BITS == 0 static const struct { int f_base; const char *f; int z_base; const char *want_num; const char *want_den; } data[] = { { -2, "0", 16, "0", "1" }, { -2, "1", 16, "1", "1" }, { -2, "1@1", 16, "2", "1" }, { -2, "1@2", 16, "4", "1" }, { -2, "1@3", 16, "8", "1" }, { -2, "1@30", 16, "40000000", "1" }, { -2, "1@31", 16, "80000000", "1" }, { -2, "1@32", 16, "100000000", "1" }, { -2, "1@33", 16, "200000000", "1" }, { -2, "1@34", 16, "400000000", "1" }, { -2, "1@62", 16, "4000000000000000", "1" }, { -2, "1@63", 16, "8000000000000000", "1" }, { -2, "1@64", 16, "10000000000000000", "1" }, { -2, "1@65", 16, "20000000000000000", "1" }, { -2, "1@66", 16, "40000000000000000", "1" }, { -2, "1@126", 16, "40000000000000000000000000000000", "1" }, { -2, "1@127", 16, "80000000000000000000000000000000", "1" }, { -2, "1@128", 16, "100000000000000000000000000000000", "1" }, { -2, "1@129", 16, "200000000000000000000000000000000", "1" }, { -2, "1@130", 16, "400000000000000000000000000000000", "1" }, { -2, "1@-1", 16, "1", "2" }, { -2, "1@-2", 16, "1", "4" }, { -2, "1@-3", 16, "1", "8" }, { -2, "1@-30", 16, "1", "40000000" }, { -2, "1@-31", 16, "1", "80000000" }, { -2, "1@-32", 16, "1", "100000000" }, { -2, "1@-33", 16, "1", "200000000" }, { -2, "1@-34", 16, "1", "400000000" }, { -2, "1@-62", 16, "1", "4000000000000000" }, { -2, "1@-63", 16, "1", "8000000000000000" }, { -2, "1@-64", 16, "1", "10000000000000000" }, { -2, "1@-65", 16, "1", "20000000000000000" }, { -2, "1@-66", 16, "1", "40000000000000000" }, { -2, "1@-126", 16, "1", "40000000000000000000000000000000" }, { -2, "1@-127", 16, "1", "80000000000000000000000000000000" }, { -2, "1@-128", 16, "1", "100000000000000000000000000000000" }, { -2, "1@-129", 16, "1", "200000000000000000000000000000000" }, { -2, "1@-130", 16, "1", "400000000000000000000000000000000" }, { -2, "1@-30", 16, "1", "40000000" }, { -2, "1@-31", 16, "1", "80000000" }, { -2, "1@-32", 16, "1", "100000000" }, { -2, "1@-33", 16, "1", "200000000" }, { -2, "1@-34", 16, "1", "400000000" }, { -2, "11@-62", 16, "3", "4000000000000000" }, { -2, "11@-63", 16, "3", "8000000000000000" }, { -2, "11@-64", 16, "3", "10000000000000000" }, { -2, "11@-65", 16, "3", "20000000000000000" }, { -2, "11@-66", 16, "3", "40000000000000000" }, { 16, "80000000.00000001", 16, "8000000000000001", "100000000" }, { 16, "80000000.00000008", 16, "1000000000000001", "20000000" }, { 16, "80000000.8", 16, "100000001", "2" }, }; mpf_t f; mpq_t got; mpz_t want_num, want_den; int i, neg; tests_start (); mpf_init2 (f, 1024L); mpq_init (got); mpz_init (want_num); mpz_init (want_den); for (i = 0; i < numberof (data); i++) { for (neg = 0; neg <= 1; neg++) { mpf_set_str_or_abort (f, data[i].f, data[i].f_base); mpz_set_str_or_abort (want_num, data[i].want_num, data[i].z_base); mpz_set_str_or_abort (want_den, data[i].want_den, data[i].z_base); if (neg) { mpf_neg (f, f); mpz_neg (want_num, want_num); } mpq_set_f (got, f); MPQ_CHECK_FORMAT (got); if (mpz_cmp (mpq_numref(got), want_num) != 0 || mpz_cmp (mpq_denref(got), want_den) != 0) { printf ("wrong at data[%d]\n", i); printf (" f_base %d, z_base %d\n", data[i].f_base, data[i].z_base); printf (" f \"%s\" hex ", data[i].f); mpf_out_str (stdout, 16, 0, f); printf ("\n"); printf (" want num 0x"); mpz_out_str (stdout, 16, want_num); printf ("\n"); printf (" want den 0x"); mpz_out_str (stdout, 16, want_den); printf ("\n"); printf (" got num 0x"); mpz_out_str (stdout, 16, mpq_numref(got)); printf ("\n"); printf (" got den 0x"); mpz_out_str (stdout, 16, mpq_denref(got)); printf ("\n"); abort (); } } } mpf_clear (f); mpq_clear (got); mpz_clear (want_num); mpz_clear (want_den); tests_end (); #endif exit (0); }
void check_data (void) { static const struct { const char *inp; int base; const char *want; int want_nread; } data[] = { { "0", 10, "0", 1 }, { "0/1", 10, "0", 3 }, { "0/", 10, "0", 0 }, { "/123", 10, "0", 0 }, { "blah", 10, "0", 0 }, { "123/blah", 10, "0", 0 }, { "5 /8", 10, "5", 1 }, { "5/ 8", 10, "0", 0 }, { "ff", 16, "255", 2 }, { "-ff", 16, "-255", 3 }, { "FF", 16, "255", 2 }, { "-FF", 16, "-255", 3 }, { "z", 36, "35", 1 }, { "Z", 36, "35", 1 }, { "0x0", 0, "0", 3 }, { "0x10", 0, "16", 4 }, { "-0x0", 0, "0", 4 }, { "-0x10", 0, "-16", 5 }, { "-0x10/5", 0, "-16/5", 7 }, { "00", 0, "0", 2 }, { "010", 0, "8", 3 }, { "-00", 0, "0", 3 }, { "-010", 0, "-8", 4 }, }; mpq_t got, want; long ftell_nread; int i, post, j, got_nread; FILE *fp; mpq_init (got); mpq_init (want); for (i = 0; i < numberof (data); i++) { for (post = 0; post <= 2; post++) { mpq_set_str_or_abort (want, data[i].want, 0); MPQ_CHECK_FORMAT (want); fp = fopen (FILENAME, "w+"); ASSERT_ALWAYS (fp != NULL); fputs (data[i].inp, fp); for (j = 0; j < post; j++) putc (' ', fp); fflush (fp); ASSERT_ALWAYS (! ferror(fp)); rewind (fp); got_nread = mpq_inp_str (got, fp, data[i].base); if (got_nread != 0) { ftell_nread = ftell (fp); if (got_nread != ftell_nread) { printf ("mpq_inp_str nread wrong\n"); printf (" inp \"%s\"\n", data[i].inp); printf (" base %d\n", data[i].base); printf (" got_nread %d\n", got_nread); printf (" ftell_nread %ld\n", ftell_nread); abort (); } } if (post == 0 && data[i].want_nread == strlen(data[i].inp)) { int c = getc(fp); if (c != EOF) { printf ("mpq_inp_str didn't read to EOF\n"); printf (" inp \"%s\"\n", data[i].inp); printf (" base %d\n", data[i].base); printf (" c '%c' %#x\n", c, c); abort (); } } if (got_nread != data[i].want_nread) { printf ("mpq_inp_str nread wrong\n"); printf (" inp \"%s\"\n", data[i].inp); printf (" base %d\n", data[i].base); printf (" got_nread %d\n", got_nread); printf (" want_nread %d\n", data[i].want_nread); abort (); } MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want)) { printf ("mpq_inp_str wrong result\n"); printf (" inp \"%s\"\n", data[i].inp); printf (" base %d\n", data[i].base); mpq_trace (" got ", got); mpq_trace (" want", want); abort (); } ASSERT_ALWAYS (fclose (fp) == 0); } } mpq_clear (got); mpq_clear (want); }
void check_monotonic (int argc, char **argv) { mpq_t a; mp_size_t size; int reps = 100; int i, j; double last_d, new_d; mpq_t qlast_d, qnew_d; mpq_t eps; if (argc == 2) reps = atoi (argv[1]); /* The idea here is to test the monotonousness of mpq_get_d by adding numbers to the numerator and denominator. */ mpq_init (a); mpq_init (eps); mpq_init (qlast_d); mpq_init (qnew_d); for (i = 0; i < reps; i++) { size = urandom () % SIZE - SIZE/2; mpz_random2 (mpq_numref (a), size); do { size = urandom () % SIZE - SIZE/2; mpz_random2 (mpq_denref (a), size); } while (mpz_cmp_ui (mpq_denref (a), 0) == 0); mpq_canonicalize (a); last_d = mpq_get_d (a); mpq_set_d (qlast_d, last_d); for (j = 0; j < 10; j++) { size = urandom () % EPSIZE + 1; mpz_random2 (mpq_numref (eps), size); size = urandom () % EPSIZE + 1; mpz_random2 (mpq_denref (eps), size); mpq_canonicalize (eps); mpq_add (a, a, eps); mpq_canonicalize (a); new_d = mpq_get_d (a); if (last_d > new_d) { printf ("\nERROR (test %d/%d): bad mpq_get_d results\n", i, j); printf ("last: %.16g\n", last_d); printf (" new: %.16g\n", new_d); dump (a); abort (); } mpq_set_d (qnew_d, new_d); MPQ_CHECK_FORMAT (qnew_d); if (mpq_cmp (qlast_d, qnew_d) > 0) { printf ("ERROR (test %d/%d): bad mpq_set_d results\n", i, j); printf ("last: %.16g\n", last_d); dump (qlast_d); printf (" new: %.16g\n", new_d); dump (qnew_d); abort (); } last_d = new_d; mpq_set (qlast_d, qnew_d); } } mpq_clear (a); mpq_clear (eps); mpq_clear (qlast_d); mpq_clear (qnew_d); }
void check_data (void) { static const struct { const char *q; mpir_si n; mpir_ui d; int want; } data[] = { { "0", 0, 1, 0 }, { "0", 0, 123, 0 }, { "0", 0, GMP_UI_MAX, 0 }, { "1", 0, 1, 1 }, { "1", 0, 123, 1 }, { "1", 0, GMP_UI_MAX, 1 }, { "-1", 0, 1, -1 }, { "-1", 0, 123, -1 }, { "-1", 0, GMP_UI_MAX, -1 }, { "123", 123, 1, 0 }, { "124", 123, 1, 1 }, { "122", 123, 1, -1 }, { "-123", 123, 1, -1 }, { "-124", 123, 1, -1 }, { "-122", 123, 1, -1 }, { "123", -123, 1, 1 }, { "124", -123, 1, 1 }, { "122", -123, 1, 1 }, { "-123", -123, 1, 0 }, { "-124", -123, 1, -1 }, { "-122", -123, 1, 1 }, { "5/7", 3,4, -1 }, { "5/7", -3,4, 1 }, { "-5/7", 3,4, -1 }, { "-5/7", -3,4, 1 }, }; mpq_t q; int i, got; mpq_init (q); for (i = 0; i < numberof (data); i++) { mpq_set_str_or_abort (q, data[i].q, 0); MPQ_CHECK_FORMAT (q); got = mpq_cmp_si (q, data[i].n, data[i].d); if (SGN(got) != data[i].want) { printf ("mpq_cmp_si wrong\n"); error: mpq_trace (" q", q); printf (" n=%Md\n", data[i].n); printf (" d=%Mu\n", data[i].d); printf (" got=%d\n", got); printf (" want=%Md\n", data[i].want); abort (); } if (data[i].n == 0) { got = mpq_cmp_si (q, 0L, data[i].d); if (SGN(got) != data[i].want) { printf ("mpq_cmp_si wrong\n"); goto error; } } } mpq_clear (q); }
void check_n (void) { { int n = -1; check_one ("blah", "%nblah", &n); ASSERT_ALWAYS (n == 0); } { int n = -1; check_one ("hello ", "hello %n", &n); ASSERT_ALWAYS (n == 6); } { int n = -1; check_one ("hello world", "hello %n world", &n); ASSERT_ALWAYS (n == 6); } #define CHECK_N(type, string) \ do { \ type x[2]; \ char fmt[128]; \ \ x[0] = ~ (type) 0; \ x[1] = ~ (type) 0; \ sprintf (fmt, "%%d%%%sn%%d", string); \ check_one ("123456", fmt, 123, &x[0], 456); \ \ /* should write whole of x[0] and none of x[1] */ \ ASSERT_ALWAYS (x[0] == 3); \ ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \ \ } while (0) CHECK_N (mp_limb_t, "M"); CHECK_N (char, "hh"); CHECK_N (long, "l"); #if HAVE_LONG_LONG CHECK_N (long long, "L"); #endif #if HAVE_INTMAX_T CHECK_N (intmax_t, "j"); #endif #if HAVE_PTRDIFF_T CHECK_N (ptrdiff_t, "t"); #endif CHECK_N (short, "h"); CHECK_N (size_t, "z"); { mpz_t x[2]; mpz_init_set_si (x[0], -987L); mpz_init_set_si (x[1], 654L); check_one ("123456", "%d%Zn%d", 123, x[0], 456); MPZ_CHECK_FORMAT (x[0]); MPZ_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0); ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0); mpz_clear (x[0]); mpz_clear (x[1]); } { mpq_t x[2]; mpq_init (x[0]); mpq_init (x[1]); mpq_set_ui (x[0], -987L, 654L); mpq_set_ui (x[1], 4115L, 226L); check_one ("123456", "%d%Qn%d", 123, x[0], 456); MPQ_CHECK_FORMAT (x[0]); MPQ_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0); ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0); mpq_clear (x[0]); mpq_clear (x[1]); } { mpf_t x[2]; mpf_init (x[0]); mpf_init (x[1]); mpf_set_ui (x[0], -987L); mpf_set_ui (x[1], 654L); check_one ("123456", "%d%Fn%d", 123, x[0], 456); MPF_CHECK_FORMAT (x[0]); MPF_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0); ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0); mpf_clear (x[0]); mpf_clear (x[1]); } { mp_limb_t a[5]; mp_limb_t a_want[numberof(a)]; mp_size_t i; a[0] = 123; check_one ("blah", "bl%Nnah", a, (mp_size_t) 0); ASSERT_ALWAYS (a[0] == 123); MPN_ZERO (a_want, numberof (a_want)); for (i = 1; i < numberof (a); i++) { check_one ("blah", "bl%Nnah", a, i); a_want[0] = 2; ASSERT_ALWAYS (mpn_cmp (a, a_want, i) == 0); } } }
int main (int argc, char **argv) { static const struct { struct pair_t left; unsigned long n; struct pair_t right; } data[] = { { {"0","1"}, 0, {"0","1"} }, { {"0","1"}, 1, {"0","1"} }, { {"0","1"}, 2, {"0","1"} }, { {"1","1"}, 0, {"1","1"} }, { {"1","1"}, 1, {"2","1"} }, { {"1","1"}, 2, {"4","1"} }, { {"1","1"}, 3, {"8","1"} }, { {"1","1"}, 31, {"0x80000000","1"} }, { {"1","1"}, 32, {"0x100000000","1"} }, { {"1","1"}, 33, {"0x200000000","1"} }, { {"1","1"}, 63, {"0x8000000000000000","1"} }, { {"1","1"}, 64, {"0x10000000000000000","1"} }, { {"1","1"}, 65, {"0x20000000000000000","1"} }, { {"1","1"}, 95, {"0x800000000000000000000000","1"} }, { {"1","1"}, 96, {"0x1000000000000000000000000","1"} }, { {"1","1"}, 97, {"0x2000000000000000000000000","1"} }, { {"1","1"}, 127, {"0x80000000000000000000000000000000","1"} }, { {"1","1"}, 128, {"0x100000000000000000000000000000000","1"} }, { {"1","1"}, 129, {"0x200000000000000000000000000000000","1"} }, { {"1","2"}, 31, {"0x40000000","1"} }, { {"1","2"}, 32, {"0x80000000","1"} }, { {"1","2"}, 33, {"0x100000000","1"} }, { {"1","2"}, 63, {"0x4000000000000000","1"} }, { {"1","2"}, 64, {"0x8000000000000000","1"} }, { {"1","2"}, 65, {"0x10000000000000000","1"} }, { {"1","2"}, 95, {"0x400000000000000000000000","1"} }, { {"1","2"}, 96, {"0x800000000000000000000000","1"} }, { {"1","2"}, 97, {"0x1000000000000000000000000","1"} }, { {"1","2"}, 127, {"0x40000000000000000000000000000000","1"} }, { {"1","2"}, 128, {"0x80000000000000000000000000000000","1"} }, { {"1","2"}, 129, {"0x100000000000000000000000000000000","1"} }, { {"1","0x80000000"}, 30, {"1","2"} }, { {"1","0x80000000"}, 31, {"1","1"} }, { {"1","0x80000000"}, 32, {"2","1"} }, { {"1","0x80000000"}, 33, {"4","1"} }, { {"1","0x80000000"}, 62, {"0x80000000","1"} }, { {"1","0x80000000"}, 63, {"0x100000000","1"} }, { {"1","0x80000000"}, 64, {"0x200000000","1"} }, { {"1","0x80000000"}, 94, {"0x8000000000000000","1"} }, { {"1","0x80000000"}, 95, {"0x10000000000000000","1"} }, { {"1","0x80000000"}, 96, {"0x20000000000000000","1"} }, { {"1","0x80000000"}, 126, {"0x800000000000000000000000","1"} }, { {"1","0x80000000"}, 127, {"0x1000000000000000000000000","1"} }, { {"1","0x80000000"}, 128, {"0x2000000000000000000000000","1"} }, { {"1","0x100000000"}, 1, {"1","0x80000000"} }, { {"1","0x100000000"}, 2, {"1","0x40000000"} }, { {"1","0x100000000"}, 3, {"1","0x20000000"} }, { {"1","0x10000000000000000"}, 1, {"1","0x8000000000000000"} }, { {"1","0x10000000000000000"}, 2, {"1","0x4000000000000000"} }, { {"1","0x10000000000000000"}, 3, {"1","0x2000000000000000"} }, }; void (*fun) (mpq_ptr, mpq_srcptr, unsigned long); const struct pair_t *p_start, *p_want; const char *name; mpq_t sep, got, want; mpq_ptr q; int i, muldiv, sign, overlap; tests_start (); mpq_init (sep); mpq_init (got); mpq_init (want); for (i = 0; i < numberof (data); i++) { for (muldiv = 0; muldiv < 2; muldiv++) { if (muldiv == 0) { fun = mpq_mul_2exp; name = "mpq_mul_2exp"; p_start = &data[i].left; p_want = &data[i].right; } else { fun = mpq_div_2exp; name = "mpq_div_2exp"; p_start = &data[i].right; p_want = &data[i].left; } for (sign = 0; sign <= 1; sign++) { mpz_set_str_or_abort (mpq_numref(want), p_want->num, 0); mpz_set_str_or_abort (mpq_denref(want), p_want->den, 0); if (sign) mpq_neg (want, want); for (overlap = 0; overlap <= 1; overlap++) { q = overlap ? got : sep; /* initial garbage in "got" */ mpq_set_ui (got, 123L, 456L); mpz_set_str_or_abort (mpq_numref(q), p_start->num, 0); mpz_set_str_or_abort (mpq_denref(q), p_start->den, 0); if (sign) mpq_neg (q, q); (*fun) (got, q, data[i].n); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want)) { printf ("%s wrong at data[%d], sign %d, overlap %d\n", name, i, sign, overlap); printf (" num \"%s\"\n", p_start->num); printf (" den \"%s\"\n", p_start->den); printf (" n %lu\n", data[i].n); printf (" got "); mpq_out_str (stdout, 16, got); printf (" (hex)\n"); printf (" want "); mpq_out_str (stdout, 16, want); printf (" (hex)\n"); abort (); } } } } } check_random (); mpq_clear (sep); mpq_clear (got); mpq_clear (want); tests_end (); exit (0); }