void check_one (mpz_ptr x, mpz_ptr y, int want_cmp, int want_cmpabs) { int got; got = mpz_cmp (x, y); if (( got < 0) != (want_cmp < 0) || (got == 0) != (want_cmp == 0) || (got > 0) != (want_cmp > 0)) { printf ("mpz_cmp got %d want %d\n", got, want_cmp); mpz_trace ("x", x); mpz_trace ("y", y); abort (); } got = mpz_cmpabs (x, y); if (( got < 0) != (want_cmpabs < 0) || (got == 0) != (want_cmpabs == 0) || (got > 0) != (want_cmpabs > 0)) { printf ("mpz_cmpabs got %d want %d\n", got, want_cmpabs); mpz_trace ("x", x); mpz_trace ("y", y); abort (); } }
void check_one (mpz_srcptr want, int fail, int base, const char *str) { mpz_t got; MPZ_CHECK_FORMAT (want); mp_trace_base = (base == 0 ? 16 : base); mpz_init (got); if (mpz_set_str (got, str, base) != fail) { printf ("mpz_set_str unexpectedly failed\n"); printf (" base %d\n", base); printf (" str \"%s\"\n", str); abort (); } MPZ_CHECK_FORMAT (got); if (fail == 0 && mpz_cmp (got, want) != 0) { printf ("mpz_set_str wrong\n"); printf (" base %d\n", base); printf (" str \"%s\"\n", str); mpz_trace ("got ", got); mpz_trace ("want", want); abort (); } mpz_clear (got); }
/* Check that hardware rounding doesn't make mpz_get_d_2exp return a value outside its defined range. */ static void check_round (void) { static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 }; mpz_t z; double got; long got_exp; int i, rnd_mode, old_rnd_mode; mpz_init (z); old_rnd_mode = tests_hardware_getround (); for (rnd_mode = 0; rnd_mode < 4; rnd_mode++) { tests_hardware_setround (rnd_mode); for (i = 0; i < numberof (data); i++) { mpz_set_ui (z, 1L); mpz_mul_2exp (z, z, data[i]); mpz_sub_ui (z, z, 1L); got = mpz_get_d_2exp (&got_exp, z); if (got < 0.5 || got >= 1.0) { printf ("mpz_get_d_2exp wrong on 2**%lu-1\n", data[i]); printf ("result out of range, expect 0.5 <= got < 1.0\n"); printf (" rnd_mode = %d\n", rnd_mode); printf (" data[i] = %lu\n", data[i]); mpz_trace (" z ", z); d_trace (" got ", got); printf (" got exp %ld\n", got_exp); abort(); } mpz_neg (z, z); got = mpz_get_d_2exp (&got_exp, z); if (got <= -1.0 || got > -0.5) { printf ("mpz_get_d_2exp wrong on -2**%lu-1\n", data[i]); printf ("result out of range, expect -1.0 < got <= -0.5\n"); printf (" rnd_mode = %d\n", rnd_mode); printf (" data[i] = %lu\n", data[i]); mpz_trace (" z ", z); d_trace (" got ", got); printf (" got exp %ld\n", got_exp); abort(); } } } mpz_clear (z); tests_hardware_setround (old_rnd_mode); }
void compare_ui (unsigned long y) { if (mpz_cmp (got, want) != 0) { printf ("mpz_mul_ui wrong\n"); mpz_trace (" x", x); printf (" y=%lu (0x%lX)\n", y, y); mpz_trace (" got ", got); mpz_trace (" want", want); abort (); } }
/* exercise the case where mpz_clrbit or mpz_combit ends up extending a value like -2^(k*GMP_NUMB_BITS-1) when clearing bit k*GMP_NUMB_BITS-1. */ void check_clr_extend (void) { mpz_t got, want; unsigned long i; int f; mpz_init (got); mpz_init (want); for (i = 1; i < 5; i++) { for (f = 0; f <= 1; f++) { /* lots of 1 bits in _mp_d */ mpz_set_ui (got, 1L); mpz_mul_2exp (got, got, 10*GMP_NUMB_BITS); mpz_sub_ui (got, got, 1L); /* value -2^(n-1) representing ..11100..00 */ mpz_set_si (got, -1L); mpz_mul_2exp (got, got, i*GMP_NUMB_BITS-1); /* complement bit n, giving ..11000..00 which is -2^n */ if (f == 0) mpz_clrbit (got, i*GMP_NUMB_BITS-1); else mpz_combit (got, i*GMP_NUMB_BITS-1); MPZ_CHECK_FORMAT (got); mpz_set_si (want, -1L); mpz_mul_2exp (want, want, i*GMP_NUMB_BITS); if (mpz_cmp (got, want) != 0) { if (f == 0) printf ("mpz_clrbit: "); else printf ("mpz_combit: "); printf ("wrong after extension\n"); mpz_trace ("got ", got); mpz_trace ("want", want); abort (); } } } mpz_clear (got); mpz_clear (want); }
static void check_onebit (void) { static const unsigned long data[] = { 1, 32, 52, 53, 54, 63, 64, 65, 128, 256, 511, 512, 513 }; mpz_t z; double got, want; long got_exp, want_exp; int i; mpz_init (z); for (i = 0; i < numberof (data); i++) { mpz_set_ui (z, 1L); mpz_mul_2exp (z, z, data[i]); want = 0.5; want_exp = data[i] + 1; got = mpz_get_d_2exp (&got_exp, z); if (got != want || got_exp != want_exp) { printf ("mpz_get_d_2exp wrong on 2**%ld\n", data[i]); mpz_trace (" z ", z); d_trace (" want ", want); d_trace (" got ", got); printf (" want exp %ld\n", want_exp); printf (" got exp %ld\n", got_exp); abort(); } mpz_set_si (z, -1L); mpz_mul_2exp (z, z, data[i]); want = -0.5; want_exp = data[i] + 1; got = mpz_get_d_2exp (&got_exp, z); if (got != want || got_exp != want_exp) { printf ("mpz_get_d_2exp wrong on -2**%ld\n", data[i]); mpz_trace (" z ", z); d_trace (" want ", want); d_trace (" got ", got); printf (" want exp %ld\n", want_exp); printf (" got exp %ld\n", got_exp); abort(); } } mpz_clear (z); }
void check_com_negs (void) { static const struct { unsigned long bit; mp_size_t inp_size; mp_limb_t inp_n[5]; mp_size_t want_size; mp_limb_t want_n[5]; } data[] = { { GMP_NUMB_BITS, 2, { 1, 1 }, 1, { 1 } }, { GMP_NUMB_BITS+1, 2, { 1, 1 }, 2, { 1, 3 } }, { GMP_NUMB_BITS, 2, { 0, 1 }, 2, { 0, 2 } }, { GMP_NUMB_BITS+1, 2, { 0, 1 }, 2, { 0, 3 } }, }; mpz_t inp, got, want; int i; mpz_init (got); mpz_init (want); mpz_init (inp); for (i = 0; i < numberof (data); i++) { mpz_set_n (inp, data[i].inp_n, data[i].inp_size); mpz_neg (inp, inp); mpz_set_n (want, data[i].want_n, data[i].want_size); mpz_neg (want, want); mpz_set (got, inp); mpz_combit (got, data[i].bit); if (mpz_cmp (got, want) != 0) { printf ("mpz_combit: wrong on neg data[%d]\n", i); mpz_trace ("inp ", inp); printf ("bit %lu\n", data[i].bit); mpz_trace ("got ", got); mpz_trace ("want", want); abort (); } } mpz_clear (inp); mpz_clear (got); mpz_clear (want); }
/* Print "name=value\n" to stdout for an mpn style ptr,size. */ void mpn_trace (const char *name, mp_srcptr ptr, mp_size_t size) { mpz_t z; if (ptr == NULL) { mpz_trace (name, NULL); return; } MPN_NORMALIZE (ptr, size); PTR(z) = (mp_ptr) ptr; SIZ(z) = size; ALLOC(z) = size; mpz_trace (name, z); }
static void check_rand (void) { gmp_randstate_ptr rands = RANDS; int i; mpz_t z; double got; long got_exp; unsigned long bits; mpz_init (z); for (i = 0; i < 200; i++) { bits = gmp_urandomm_ui (rands, 512L); mpz_urandomb (z, rands, bits); got = mpz_get_d_2exp (&got_exp, z); if (mpz_sgn (z) == 0) continue; bits = mpz_sizeinbase (z, 2); if (got < 0.5 || got >= 1.0) { printf ("mpz_get_d_2exp out of range, expect 0.5 <= got < 1.0\n"); mpz_trace (" z ", z); d_trace (" got ", got); printf (" got exp %ld\n", got_exp); abort(); } /* FIXME: If mpz_get_d_2exp rounds upwards we might have got_exp == bits+1, so leave this test disabled until we decide if that's what should happen, or not. */ #if 0 if (got_exp != bits) { printf ("mpz_get_d_2exp wrong exponent\n", i); mpz_trace (" z ", z); d_trace (" bits ", bits); d_trace (" got ", got); printf (" got exp %ld\n", got_exp); abort(); } #endif } mpz_clear (z); }
/* Exercise mpz_perfect_square_p compared to what mpz_sqrt says. */ void check_sqrt (int reps) { mpz_t x2, x2t, x; mp_size_t x2n; int res; int i; /* int cnt = 0; */ gmp_randstate_ptr rands = RANDS; mpz_t bs; mpz_init (bs); mpz_init (x2); mpz_init (x); mpz_init (x2t); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 9); x2n = mpz_get_ui (bs); mpz_rrandomb (x2, rands, x2n); /* mpz_out_str (stdout, -16, x2); puts (""); */ res = mpz_perfect_square_p (x2); mpz_sqrt (x, x2); mpz_mul (x2t, x, x); if (res != (mpz_cmp (x2, x2t) == 0)) { printf ("mpz_perfect_square_p and mpz_sqrt differ\n"); mpz_trace (" x ", x); mpz_trace (" x2 ", x2); mpz_trace (" x2t", x2t); printf (" mpz_perfect_square_p %d\n", res); printf (" mpz_sqrt %d\n", mpz_cmp (x2, x2t) == 0); abort (); } /* cnt += res != 0; */ } /* printf ("%d/%d perfect squares\n", cnt, reps); */ mpz_clear (bs); mpz_clear (x2); mpz_clear (x); mpz_clear (x2t); }
void check_twobits (void) { unsigned long i, j, got, want; mpz_t x, y; mpz_init (x); mpz_init (y); for (i = 0; i < 5 * GMP_NUMB_BITS; i++) { for (j = 0; j < 5 * GMP_NUMB_BITS; j++) { mpz_set_ui (x, 0L); mpz_setbit (x, i); mpz_set_ui (y, 0L); mpz_setbit (y, j); want = 2 * (i != j); got = mpz_hamdist (x, y); if (got != want) { printf ("mpz_hamdist wrong on 2 bits pos/pos\n"); wrong: printf (" i %lu\n", i); printf (" j %lu\n", j); printf (" got %lu\n", got); printf (" want %lu\n", want); mpz_trace (" x ", x); mpz_trace (" y ", y); abort(); } mpz_neg (x, x); mpz_neg (y, y); want = ABS ((long) (i-j)); got = mpz_hamdist (x, y); if (got != want) { printf ("mpz_hamdist wrong on 2 bits neg/neg\n"); goto wrong; } } } mpz_clear (x); mpz_clear (y); }
void check_data (void) { static const struct { const char *a; const char *b; const char *want; } data[] = { /* This tickled a bug in gmp 4.1.2 mpn/x86/k6/gcd_finda.asm. */ { "0x3FFC000007FFFFFFFFFF00000000003F83FFFFFFFFFFFFFFF80000000000000001", "0x1FFE0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000000000000001", "5" } }; mpz_t a, b, got, want; int i; mpz_init (a); mpz_init (b); mpz_init (got); mpz_init (want); for (i = 0; i < numberof (data); i++) { mpz_set_str_or_abort (a, data[i].a, 0); mpz_set_str_or_abort (b, data[i].b, 0); mpz_set_str_or_abort (want, data[i].want, 0); mpz_gcd (got, a, b); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("mpz_gcd wrong on data[%d]\n", i); printf (" a %s\n", data[i].a); printf (" b %s\n", data[i].b); mpz_trace (" a", a); mpz_trace (" b", b); mpz_trace (" want", want); mpz_trace (" got ", got); abort (); } } mpz_clear (a); mpz_clear (b); mpz_clear (got); mpz_clear (want); }
void check_random (int argc, char *argv[]) { gmp_randstate_ptr rands = RANDS; int reps = 5000; mpz_t a, q, got; int i, qneg; unsigned long d; if (argc == 2) reps = atoi (argv[1]); mpz_init (a); mpz_init (q); mpz_init (got); for (i = 0; i < reps; i++) { d = (unsigned long) urandom(); mpz_erandomb (q, rands, 512); mpz_mul_ui (a, q, d); for (qneg = 0; qneg <= 1; qneg++) { mpz_divexact_ui (got, a, d); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, q) != 0) { printf ("mpz_divexact_ui wrong\n"); mpz_trace (" a", a); printf (" d=%lu\n", d); mpz_trace (" q", q); mpz_trace (" got", got); abort (); } mpz_neg (q, q); mpz_neg (a, a); } } mpz_clear (a); mpz_clear (q); mpz_clear (got); }
void check_one (mpz_srcptr a, unsigned long d, int want) { int got; got = (mpz_divisible_2exp_p (a, d) != 0); if (want != got) { printf ("mpz_divisible_2exp_p wrong\n"); printf (" expected %d got %d\n", want, got); mpz_trace (" a", a); printf (" d=%lu\n", d); mp_trace_base = -16; mpz_trace (" a", a); printf (" d=0x%lX\n", d); abort (); } }
/* Print "namenum=value\n" to stdout for an mpz_t value. "name" should have a "%d" to get the number. */ void mpz_tracen (const char *name, int num, mpz_srcptr z) { if (name != NULL && name[0] != '\0') { printf (name, num); putchar ('='); } mpz_trace (NULL, z); }
void check_one (mpz_srcptr a, mpz_srcptr d, int want) { int got; if (mpz_fits_ulong_p (d)) { unsigned long u = mpz_get_ui (d); got = (mpz_divisible_ui_p (a, u) != 0); if (want != got) { printf ("mpz_divisible_ui_p wrong\n"); printf (" expected %d got %d\n", want, got); mpz_trace (" a", a); printf (" d=%lu\n", u); mp_trace_base = -16; mpz_trace (" a", a); printf (" d=0x%lX\n", u); abort (); } } got = (mpz_divisible_p (a, d) != 0); if (want != got) { printf ("mpz_divisible_p wrong\n"); printf (" expected %d got %d\n", want, got); mpz_trace (" a", a); mpz_trace (" d", d); mp_trace_base = -16; mpz_trace (" a", a); mpz_trace (" d", d); abort (); } }
void check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y) { mpz_t want, got; mpz_init (want); mpz_init (got); mpz_mul_ui (want, x, (unsigned long) y); mpz_add (want, w, want); mpz_set (got, w); mpz_addmul_ui (got, x, (unsigned long) y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_addmul_ui fail\n"); fail: mpz_trace ("w", w); mpz_trace ("x", x); printf ("y=0x%lX %lu\n", y, y); mpz_trace ("want", want); mpz_trace ("got ", got); abort (); } mpz_mul_ui (want, x, y); mpz_sub (want, w, want); mpz_set (got, w); mpz_submul_ui (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_submul_ui fail\n"); goto fail; } mpz_clear (want); mpz_clear (got); }
void check_one (mpz_srcptr want, mpz_srcptr base, unsigned long exp) { mpz_t got; mpz_init (got); MPZ_CHECK_FORMAT (want); mpz_pow_ui (got, base, exp); if (mpz_cmp (got, want)) { printf ("mpz_pow_ui wrong\n"); mpz_trace (" base", base); printf (" exp = %lu (0x%lX)\n", exp, exp); mpz_trace (" got ", got); mpz_trace (" want", want); abort (); } mpz_set (got, base); mpz_pow_ui (got, got, exp); if (mpz_cmp (got, want)) { printf ("mpz_pow_ui wrong\n"); mpz_trace (" base", base); printf (" exp = %lu (0x%lX)\n", exp, exp); mpz_trace (" got ", got); mpz_trace (" want", want); abort (); } if (mpz_fits_ulong_p (base)) { unsigned long base_u = mpz_get_ui (base); mpz_ui_pow_ui (got, base_u, exp); if (mpz_cmp (got, want)) { printf ("mpz_ui_pow_ui wrong\n"); printf (" base=%lu (0x%lX)\n", base_u, base_u); printf (" exp = %lu (0x%lX)\n", exp, exp); mpz_trace (" got ", got); mpz_trace (" want", want); abort (); } } mpz_clear (got); }
/* Try mpz_set_d on values 2^i+1, while such a value fits a double. */ void check_2n_plus_1 (void) { volatile double p, d, diff; mpz_t want, got; int i; mpz_init (want); mpz_init (got); p = 1.0; mpz_set_ui (want, 2L); /* gives 3 on first step */ for (i = 1; i < 500; i++) { mpz_mul_2exp (want, want, 1L); mpz_sub_ui (want, want, 1L); /* want = 2^i+1 */ p *= 2.0; /* p = 2^i */ d = p + 1.0; diff = d - p; if (diff != 1.0) break; /* rounding occurred, stop now */ mpz_set_d (got, d); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("mpz_set_d wrong on 2^%d+1\n", i); d_trace (" d ", d); mpz_trace (" got ", got); mpz_trace (" want ", want); abort (); } } mpz_clear (want); mpz_clear (got); }
void check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y) { mpz_t want, got; mpz_init (want); mpz_init (got); mpz_mul (want, x, y); mpz_add (want, w, want); mpz_set (got, w); mpz_addmul (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_addmul fail\n"); fail: mpz_trace ("w", w); mpz_trace ("x", x); mpz_trace ("y", y); mpz_trace ("want", want); mpz_trace ("got ", got); abort (); } mpz_mul (want, x, y); mpz_sub (want, w, want); mpz_set (got, w); mpz_submul (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_submul fail\n"); goto fail; } mpz_clear (want); mpz_clear (got); }
void check_rand (void) { gmp_randstate_t rands; unsigned long got, want; int i; mpz_t x, y; mpz_init (x); mpz_init (y); gmp_randinit_default(rands); for (i = 0; i < 2000; i++) { mpz_erandomb (x, rands, 6 * GMP_NUMB_BITS); mpz_negrandom (x, rands); mpz_mul_2exp (x, x, urandom(rands) % (4 * GMP_NUMB_BITS)); mpz_erandomb (y, rands, 6 * GMP_NUMB_BITS); mpz_negrandom (y, rands); mpz_mul_2exp (y, y, urandom(rands) % (4 * GMP_NUMB_BITS)); want = refmpz_hamdist (x, y); got = mpz_hamdist (x, y); if (got != want) { printf ("mpz_hamdist wrong on random\n"); printf (" got %lu\n", got); printf (" want %lu\n", want); mpz_trace (" x ", x); mpz_trace (" y ", y); abort(); } } mpz_clear (x); mpz_clear (y); gmp_randclear(rands); }
void check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want) { int got; int swap; for (swap = 0; swap <= 1; swap++) { got = (mpz_congruent_p (a, c, d) != 0); if (want != got) { printf ("mpz_congruent_p wrong\n"); printf (" expected %d got %d\n", want, got); mpz_trace (" a", a); mpz_trace (" c", c); mpz_trace (" d", d); mp_trace_base = -16; mpz_trace (" a", a); mpz_trace (" c", c); mpz_trace (" d", d); abort (); } if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d)) { unsigned long uc = mpz_get_ui (c); unsigned long ud = mpz_get_ui (d); got = (mpz_congruent_ui_p (a, uc, ud) != 0); if (want != got) { printf ("mpz_congruent_ui_p wrong\n"); printf (" expected %d got %d\n", want, got); mpz_trace (" a", a); printf (" c=%lu\n", uc); printf (" d=%lu\n", ud); mp_trace_base = -16; mpz_trace (" a", a); printf (" c=0x%lX\n", uc); printf (" d=0x%lX\n", ud); abort (); } } MPZ_SRCPTR_SWAP (a, c); } }
void check_sequence (int argc, char *argv[]) { unsigned long n; unsigned long limit = 100 * BITS_PER_MP_LIMB; mpz_t want_ln, want_ln1, got_ln, got_ln1; if (argc > 1 && argv[1][0] == 'x') limit = ULONG_MAX; else if (argc > 1) limit = atoi (argv[1]); /* start at n==0 */ mpz_init_set_si (want_ln1, -1); /* L[-1] */ mpz_init_set_ui (want_ln, 2); /* L[0] */ mpz_init (got_ln); mpz_init (got_ln1); for (n = 0; n < limit; n++) { mpz_lucnum2_ui (got_ln, got_ln1, n); MPZ_CHECK_FORMAT (got_ln); MPZ_CHECK_FORMAT (got_ln1); if (mpz_cmp (got_ln, want_ln) != 0 || mpz_cmp (got_ln1, want_ln1) != 0) { printf ("mpz_lucnum2_ui(%lu) wrong\n", n); mpz_trace ("want ln ", want_ln); mpz_trace ("got ln ", got_ln); mpz_trace ("want ln1", want_ln1); mpz_trace ("got ln1", got_ln1); abort (); } mpz_lucnum_ui (got_ln, n); MPZ_CHECK_FORMAT (got_ln); if (mpz_cmp (got_ln, want_ln) != 0) { printf ("mpz_lucnum_ui(%lu) wrong\n", n); mpz_trace ("want ln", want_ln); mpz_trace ("got ln", got_ln); abort (); } mpz_add (want_ln1, want_ln1, want_ln); /* L[n+1] = L[n] + L[n-1] */ mpz_swap (want_ln1, want_ln); } mpz_clear (want_ln); mpz_clear (want_ln1); mpz_clear (got_ln); mpz_clear (got_ln1); }
void check_modulo (void) { static const unsigned long divisor[] = PERFSQR_DIVISORS; unsigned long i, j; mpz_t alldiv, others, n; mpz_init (alldiv); mpz_init (others); mpz_init (n); /* product of all divisors */ mpz_set_ui (alldiv, 1L); for (i = 0; i < numberof (divisor); i++) mpz_mul_ui (alldiv, alldiv, divisor[i]); for (i = 0; i < numberof (divisor); i++) { /* product of all divisors except i */ mpz_set_ui (others, 1L); for (j = 0; j < numberof (divisor); j++) if (i != j) mpz_mul_ui (others, others, divisor[j]); for (j = 1; j <= divisor[i]; j++) { /* square */ mpz_mul_ui (n, others, j); mpz_mul (n, n, n); if (! mpz_perfect_square_p (n)) { printf ("mpz_perfect_square_p got 0, want 1\n"); mpz_trace (" n", n); abort (); } } } mpz_clear (alldiv); mpz_clear (others); mpz_clear (n); }
void check_onebit (void) { int i; mpz_t z; double got, want; /* FIXME: It'd be better to base this on the float format. */ #ifdef __vax int limit = 127; /* vax fp numbers have limited range */ #else int limit = 512; #endif mpz_init (z); mpz_set_ui (z, 1L); want = 1.0; for (i = 0; i < limit; i++) { got = mpz_get_d (z); if (got != want) { printf ("mpz_get_d wrong on 2**%d\n", i); mpz_trace (" z ", z); printf (" want %.20g\n", want); printf (" got %.20g\n", got); abort(); } mpz_mul_2exp (z, z, 1L); want *= 2.0; } mpz_clear (z); }
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_z (void) { static const struct { const char *fmt; const char *input; const char *want; int want_ret; long want_ftell; int want_upto; int not_glibc; } data[] = { { "%Zd", "0", "0", 1, -1, -1 }, { "%Zd", "1", "1", 1, -1, -1 }, { "%Zd", "123", "123", 1, -1, -1 }, { "%Zd", "+0", "0", 1, -1, -1 }, { "%Zd", "+1", "1", 1, -1, -1 }, { "%Zd", "+123", "123", 1, -1, -1 }, { "%Zd", "-0", "0", 1, -1, -1 }, { "%Zd", "-1", "-1", 1, -1, -1 }, { "%Zd", "-123", "-123", 1, -1, -1 }, { "%Zo", "0", "0", 1, -1, -1 }, { "%Zo", "173", "123", 1, -1, -1 }, { "%Zo", "+0", "0", 1, -1, -1 }, { "%Zo", "+173", "123", 1, -1, -1 }, { "%Zo", "-0", "0", 1, -1, -1 }, { "%Zo", "-173", "-123", 1, -1, -1 }, { "%Zx", "0", "0", 1, -1, -1 }, { "%Zx", "7b", "123", 1, -1, -1 }, { "%Zx", "7b", "123", 1, -1, -1 }, { "%Zx", "+0", "0", 1, -1, -1 }, { "%Zx", "+7b", "123", 1, -1, -1 }, { "%Zx", "+7b", "123", 1, -1, -1 }, { "%Zx", "-0", "-0", 1, -1, -1 }, { "%Zx", "-7b", "-123", 1, -1, -1 }, { "%Zx", "-7b", "-123", 1, -1, -1 }, { "%ZX", "0", "0", 1, -1, -1 }, { "%ZX", "7b", "123", 1, -1, -1 }, { "%ZX", "7b", "123", 1, -1, -1 }, { "%ZX", "+0", "0", 1, -1, -1 }, { "%ZX", "+7b", "123", 1, -1, -1 }, { "%ZX", "+7b", "123", 1, -1, -1 }, { "%ZX", "-0", "-0", 1, -1, -1 }, { "%ZX", "-7b", "-123", 1, -1, -1 }, { "%ZX", "-7b", "-123", 1, -1, -1 }, { "%Zx", "0", "0", 1, -1, -1 }, { "%Zx", "7B", "123", 1, -1, -1 }, { "%Zx", "7B", "123", 1, -1, -1 }, { "%Zx", "+0", "0", 1, -1, -1 }, { "%Zx", "+7B", "123", 1, -1, -1 }, { "%Zx", "+7B", "123", 1, -1, -1 }, { "%Zx", "-0", "-0", 1, -1, -1 }, { "%Zx", "-7B", "-123", 1, -1, -1 }, { "%Zx", "-7B", "-123", 1, -1, -1 }, { "%ZX", "0", "0", 1, -1, -1 }, { "%ZX", "7B", "123", 1, -1, -1 }, { "%ZX", "7B", "123", 1, -1, -1 }, { "%ZX", "+0", "0", 1, -1, -1 }, { "%ZX", "+7B", "123", 1, -1, -1 }, { "%ZX", "+7B", "123", 1, -1, -1 }, { "%ZX", "-0", "-0", 1, -1, -1 }, { "%ZX", "-7B", "-123", 1, -1, -1 }, { "%ZX", "-7B", "-123", 1, -1, -1 }, { "%Zi", "0", "0", 1, -1, -1 }, { "%Zi", "1", "1", 1, -1, -1 }, { "%Zi", "123", "123", 1, -1, -1 }, { "%Zi", "+0", "0", 1, -1, -1 }, { "%Zi", "+1", "1", 1, -1, -1 }, { "%Zi", "+123", "123", 1, -1, -1 }, { "%Zi", "-0", "0", 1, -1, -1 }, { "%Zi", "-1", "-1", 1, -1, -1 }, { "%Zi", "-123", "-123", 1, -1, -1 }, { "%Zi", "00", "0", 1, -1, -1 }, { "%Zi", "0173", "123", 1, -1, -1 }, { "%Zi", "+00", "0", 1, -1, -1 }, { "%Zi", "+0173", "123", 1, -1, -1 }, { "%Zi", "-00", "0", 1, -1, -1 }, { "%Zi", "-0173", "-123", 1, -1, -1 }, { "%Zi", "0x0", "0", 1, -1, -1 }, { "%Zi", "0x7b", "123", 1, -1, -1 }, { "%Zi", "0x7b", "123", 1, -1, -1 }, { "%Zi", "+0x0", "0", 1, -1, -1 }, { "%Zi", "+0x7b", "123", 1, -1, -1 }, { "%Zi", "+0x7b", "123", 1, -1, -1 }, { "%Zi", "-0x0", "-0", 1, -1, -1 }, { "%Zi", "-0x7b", "-123", 1, -1, -1 }, { "%Zi", "-0x7b", "-123", 1, -1, -1 }, { "%Zi", "0X0", "0", 1, -1, -1 }, { "%Zi", "0X7b", "123", 1, -1, -1 }, { "%Zi", "0X7b", "123", 1, -1, -1 }, { "%Zi", "+0X0", "0", 1, -1, -1 }, { "%Zi", "+0X7b", "123", 1, -1, -1 }, { "%Zi", "+0X7b", "123", 1, -1, -1 }, { "%Zi", "-0X0", "-0", 1, -1, -1 }, { "%Zi", "-0X7b", "-123", 1, -1, -1 }, { "%Zi", "-0X7b", "-123", 1, -1, -1 }, { "%Zi", "0x0", "0", 1, -1, -1 }, { "%Zi", "0x7B", "123", 1, -1, -1 }, { "%Zi", "0x7B", "123", 1, -1, -1 }, { "%Zi", "+0x0", "0", 1, -1, -1 }, { "%Zi", "+0x7B", "123", 1, -1, -1 }, { "%Zi", "+0x7B", "123", 1, -1, -1 }, { "%Zi", "-0x0", "-0", 1, -1, -1 }, { "%Zi", "-0x7B", "-123", 1, -1, -1 }, { "%Zi", "-0x7B", "-123", 1, -1, -1 }, { "%Zi", "0X0", "0", 1, -1, -1 }, { "%Zi", "0X7B", "123", 1, -1, -1 }, { "%Zi", "0X7B", "123", 1, -1, -1 }, { "%Zi", "+0X0", "0", 1, -1, -1 }, { "%Zi", "+0X7B", "123", 1, -1, -1 }, { "%Zi", "+0X7B", "123", 1, -1, -1 }, { "%Zi", "-0X0", "-0", 1, -1, -1 }, { "%Zi", "-0X7B", "-123", 1, -1, -1 }, { "%Zi", "-0X7B", "-123", 1, -1, -1 }, { "%Zd", " 0", "0", 1, -1, -1 }, { "%Zd", " 0", "0", 1, -1, -1 }, { "%Zd", " 0", "0", 1, -1, -1 }, { "%Zd", "\t0", "0", 1, -1, -1 }, { "%Zd", "\t\t0", "0", 1, -1, -1 }, { "hello%Zd", "hello0", "0", 1, -1, -1 }, { "hello%Zd", "hello 0", "0", 1, -1, -1 }, { "hello%Zd", "hello \t0", "0", 1, -1, -1 }, { "hello%Zdworld", "hello 0world", "0", 1, -1, -1 }, { "hello%*Zd", "hello0", "-999", 0, -1, -1 }, { "hello%*Zd", "hello 0", "-999", 0, -1, -1 }, { "hello%*Zd", "hello \t0", "-999", 0, -1, -1 }, { "hello%*Zdworld", "hello 0world", "-999", 0, -1, -1 }, { "%Zd", "", "-999", -1, -1, -555 }, { "%Zd", " ", "-999", -1, -1, -555 }, { " %Zd", "", "-999", -1, -1, -555 }, { "xyz%Zd", "", "-999", -1, -1, -555 }, { "%*Zd", "", "-999", -1, -1, -555 }, { " %*Zd", "", "-999", -1, -1, -555 }, { "xyz%*Zd", "", "-999", -1, -1, -555 }, { "%Zd", "xyz", "0", 0, 0, -555 }, /* match something, but invalid */ { "%Zd", "-", "-999", 0, 1, -555 }, { "%Zd", "+", "-999", 0, 1, -555 }, { "xyz%Zd", "xyz-", "-999", 0, 4, -555 }, { "xyz%Zd", "xyz+", "-999", 0, 4, -555 }, { "%Zi", "0x", "-999", 0, 2, -555 }, { "%Zi", "0X", "-999", 0, 2, -555 }, { "%Zi", "0x-", "-999", 0, 2, -555 }, { "%Zi", "0X+", "-999", 0, 2, -555 }, { "%Zi", "-0x", "-999", 0, 3, -555 }, { "%Zi", "-0X", "-999", 0, 3, -555 }, { "%Zi", "+0x", "-999", 0, 3, -555 }, { "%Zi", "+0X", "-999", 0, 3, -555 }, { "%1Zi", "1234", "1", 1, 1, 1 }, { "%2Zi", "1234", "12", 1, 2, 2 }, { "%3Zi", "1234", "123", 1, 3, 3 }, { "%4Zi", "1234", "1234", 1, 4, 4 }, { "%5Zi", "1234", "1234", 1, 4, 4 }, { "%6Zi", "1234", "1234", 1, 4, 4 }, { "%1Zi", "01234", "0", 1, 1, 1 }, { "%2Zi", "01234", "01", 1, 2, 2 }, { "%3Zi", "01234", "012", 1, 3, 3 }, { "%4Zi", "01234", "0123", 1, 4, 4 }, { "%5Zi", "01234", "01234", 1, 5, 5 }, { "%6Zi", "01234", "01234", 1, 5, 5 }, { "%7Zi", "01234", "01234", 1, 5, 5 }, { "%1Zi", "0x1234", "0", 1, 1, 1 }, { "%2Zi", "0x1234", "-999", 0, 2, -555 }, { "%3Zi", "0x1234", "0x1", 1, 3, 3 }, { "%4Zi", "0x1234", "0x12", 1, 4, 4 }, { "%5Zi", "0x1234", "0x123", 1, 5, 5 }, { "%6Zi", "0x1234", "0x1234", 1, 6, 6 }, { "%7Zi", "0x1234", "0x1234", 1, 6, 6 }, { "%8Zi", "0x1234", "0x1234", 1, 6, 6 }, { "%%xyz%Zd", "%xyz123", "123", 1, -1, -1 }, { "12%%34%Zd", "12%34567", "567", 1, -1, -1 }, { "%%%%%Zd", "%%123", "123", 1, -1, -1 }, /* various subtle EOF cases */ { "x", "", "-999", EOF, 0, -555 }, { " x", "", "-999", EOF, 0, -555 }, { "xyz", "", "-999", EOF, 0, -555 }, { " ", "", "-999", 0, 0, 0 }, { " ", " ", "-999", 0, 1, 1 }, { "%*Zd%Zd", "", "-999", EOF, 0, -555 }, { "%*Zd%Zd", "123", "-999", EOF, 3, -555 }, { "x", "x", "-999", 0, 1, 1 }, { "xyz", "x", "-999", EOF, 1, -555 }, { "xyz", "xy", "-999", EOF, 2, -555 }, { "xyz", "xyz", "-999", 0, 3, 3 }, { "%Zn", "", "0", 0, 0, 0 }, { " %Zn", "", "0", 0, 0, 0 }, { " x%Zn", "", "-999", EOF, 0, -555 }, { "xyz%Zn", "", "-999", EOF, 0, -555 }, { " x%Zn", "", "-999", EOF, 0, -555 }, { " %Zn x", " ", "-999", EOF, 1, -555 }, /* these seem to tickle a bug in glibc 2.2.4 */ { " x", " ", "-999", EOF, 1, -555, 1 }, { " xyz", " ", "-999", EOF, 1, -555, 1 }, { " x%Zn", " ", "-999", EOF, 1, -555, 1 }, }; int i, j, ignore; int got_ret, want_ret, got_upto, want_upto; mpz_t got, want; long got_l, want_ftell; int error = 0; fun_t fun; const char *name; char fmt[128]; mpz_init (got); mpz_init (want); for (i = 0; i < numberof (data); i++) { mpz_set_str_or_abort (want, data[i].want, 0); ASSERT_ALWAYS (strlen (data[i].fmt) + 2 < sizeof (fmt)); strcpy (fmt, data[i].fmt); strcat (fmt, "%n"); ignore = fmt_allignore (fmt); for (j = 0; j <= 3; j++) { want_ret = data[i].want_ret; want_ftell = data[i].want_ftell; if (want_ftell == -1) want_ftell = strlen (data[i].input); want_upto = data[i].want_upto; if (want_upto == -1) want_upto = strlen (data[i].input); switch (j) { case 0: name = "gmp_sscanf"; fun = fun_gmp_sscanf; break; case 1: name = "gmp_fscanf"; fun = fun_gmp_fscanf; break; case 2: #ifdef __GLIBC__ if (data[i].not_glibc) continue; #endif if (! libc_scanf_convert (fmt)) continue; name = "standard sscanf"; fun = fun_sscanf; break; case 3: #ifdef __GLIBC__ if (data[i].not_glibc) continue; #endif if (! libc_scanf_convert (fmt)) continue; name = "standard fscanf"; fun = fun_fscanf; break; default: ASSERT_ALWAYS (0); break; } got_upto = -555; got_ftell = -1L; switch (j) { case 0: case 1: mpz_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_l = -999L; if (ignore) got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL); else got_ret = (*fun) (data[i].input, fmt, &got_l, &got_upto); mpz_set_si (got, got_l); break; default: ASSERT_ALWAYS (0); break; } MPZ_CHECK_FORMAT (got); if (got_ret != want_ret) { printf ("%s wrong return value\n", name); error = 1; } if (want_ret == 1 && mpz_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 (" ignore %d\n", ignore); printf (" ret want=%d\n", want_ret); printf (" got =%d\n", got_ret); mpz_trace (" value want", want); mpz_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 (); } } } mpz_clear (got); mpz_clear (want); }
int main (int argc, char **argv) { mpz_t op1, op2; mpz_t prod, quot; mp_size_t size; int i; int reps = 20000; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); rands = RANDS; mp_trace_base = -16; mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (op1); mpz_init (op2); mpz_init (prod); mpz_init (quot); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */ mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (op1, rands, size); do { mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (op2, rands, size); } while (mpz_sgn (op2) == 0); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (op1, op1); if ((bsi & 2) != 0) mpz_neg (op2, op2); mpz_mul (prod, op1, op2); mpz_divexact (quot, prod, op2); MPZ_CHECK_FORMAT (quot); if (mpz_cmp (quot, op1) != 0) { printf ("Wrong results:\n"); mpz_trace (" got ", quot); mpz_trace (" want ", op1); mpz_trace (" dividend", prod); mpz_trace (" divisor ", op2); abort (); } } mpz_clear (bs); mpz_clear (op1); mpz_clear (op2); mpz_clear (prod); mpz_clear (quot); tests_end (); exit (0); }
void check_one (mpz_srcptr a, unsigned long d) { mpz_t q, r, p, d2exp; int inplace; mpz_init (d2exp); mpz_init (q); mpz_init (r); mpz_init (p); mpz_set_ui (d2exp, 1L); mpz_mul_2exp (d2exp, d2exp, d); #define INPLACE(fun,dst,src,d) \ if (inplace) \ { \ mpz_set (dst, src); \ fun (dst, dst, d); \ } \ else \ fun (dst, src, d); for (inplace = 0; inplace <= 1; inplace++) { INPLACE (mpz_fdiv_q_2exp, q, a, d); INPLACE (mpz_fdiv_r_2exp, r, a, d); mpz_mul_2exp (p, q, d); mpz_add (p, p, r); if (mpz_sgn (r) < 0 || mpz_cmp (r, d2exp) >= 0) { printf ("mpz_fdiv_r_2exp result out of range\n"); goto error; } if (mpz_cmp (p, a) != 0) { printf ("mpz_fdiv_[qr]_2exp doesn't multiply back\n"); goto error; } INPLACE (mpz_cdiv_q_2exp, q, a, d); INPLACE (mpz_cdiv_r_2exp, r, a, d); mpz_mul_2exp (p, q, d); mpz_add (p, p, r); if (mpz_sgn (r) > 0 || mpz_cmpabs (r, d2exp) >= 0) { printf ("mpz_cdiv_r_2exp result out of range\n"); goto error; } if (mpz_cmp (p, a) != 0) { printf ("mpz_cdiv_[qr]_2exp doesn't multiply back\n"); goto error; } INPLACE (mpz_tdiv_q_2exp, q, a, d); INPLACE (mpz_tdiv_r_2exp, r, a, d); mpz_mul_2exp (p, q, d); mpz_add (p, p, r); if (mpz_sgn (r) != 0 && mpz_sgn (r) != mpz_sgn (a)) { printf ("mpz_tdiv_r_2exp result wrong sign\n"); goto error; } if (mpz_cmpabs (r, d2exp) >= 0) { printf ("mpz_tdiv_r_2exp result out of range\n"); goto error; } if (mpz_cmp (p, a) != 0) { printf ("mpz_tdiv_[qr]_2exp doesn't multiply back\n"); goto error; } } mpz_clear (d2exp); mpz_clear (q); mpz_clear (r); mpz_clear (p); return; error: mpz_trace ("a", a); printf ("d=%lu\n", d); mpz_trace ("q", q); mpz_trace ("r", r); mpz_trace ("p", p); mp_trace_base = -16; mpz_trace ("a", a); printf ("d=0x%lX\n", d); mpz_trace ("q", q); mpz_trace ("r", r); mpz_trace ("p", p); abort (); }
void check_data (void) { static const struct { const char *want; size_t count; int order; size_t size; int endian; int nail; char src[64]; } data[] = { { "0", 0,1, 1,1, 0 }, { "0", 1,1, 0,1, 0 }, { "0x12345678", 4,1, 1,1, 0, { '\22', '\64', '\126', '\170' } }, { "0x12345678", 1,1, 4,1, 0, { '\22', '\64', '\126', '\170' } }, { "0x12345678", 1,-1, 4,1, 0, { '\22', '\64', '\126', '\170' } }, { "0x12345678", 4,-1, 1,-1, 0, { '\170', '\126', '\064', '\22' } }, { "0x12345678", 1,1, 4,-1, 0, { '\170', '\126', '\064', '\22' } }, { "0x12345678", 1,-1, 4,-1, 0, { '\170', '\126', '\064', '\22' } }, { "0", 5,1, 1,1, 7, { '\376', '\376', '\376', '\376', '\376' } }, { "0", 5,-1, 1,1, 7, { '\376', '\376', '\376', '\376', '\376' } }, { "0x15", 5,1, 1,1, 7, { '\377', '\376', '\377', '\376', '\377' } }, { "0", 3,1, 2,1, 1, { '\200','\000', '\200','\000', '\200','\000' }}, { "0", 3,1, 2,-1, 1, { '\000','\200', '\000','\200', '\000','\200' }}, { "0", 3,1, 2,1, 15, { '\377','\376', '\377','\376', '\377','\376' }}, { "0x2A", 3,1, 2,1, 14, { '\377','\376', '\377','\376', '\377','\376' } }, { "0x06", 3,1, 2,1, 14, { '\377','\374', '\377','\375', '\377','\376' } }, { "0x24", 3,-1, 2,1, 14, { '\377','\374', '\377','\375', '\377','\376' } }, { "0x123456789ABC", 3,1, 2,1, 0, { '\022','\064', '\126','\170', '\232','\274' } }, { "0x123456789ABC", 3,-1, 2,1, 0, { '\232','\274', '\126','\170', '\022','\064' } }, { "0x123456789ABC", 3,1, 2,-1, 0, { '\064','\022', '\170','\126', '\274','\232' } }, { "0x123456789ABC", 3,-1, 2,-1, 0, { '\274','\232', '\170','\126', '\064','\022' } }, { "0x112233445566778899AABBCC", 3,1, 4,1, 0, { '\021','\042','\063','\104', '\125','\146','\167','\210', '\231','\252','\273','\314' } }, { "0x112233445566778899AABBCC", 3,-1, 4,1, 0, { '\231','\252','\273','\314', '\125','\146','\167','\210', '\021','\042','\063','\104' } }, { "0x112233445566778899AABBCC", 3,1, 4,-1, 0, { '\104','\063','\042','\021', '\210','\167','\146','\125', '\314','\273','\252','\231' } }, { "0x112233445566778899AABBCC", 3,-1, 4,-1, 0, { '\314','\273','\252','\231', '\210','\167','\146','\125', '\104','\063','\042','\021' } }, { "0x100120023003400450056006700780089009A00AB00BC00C", 3,1, 8,1, 0, { '\020','\001','\040','\002','\060','\003','\100','\004', '\120','\005','\140','\006','\160','\007','\200','\010', '\220','\011','\240','\012','\260','\013','\300','\014' } }, { "0x100120023003400450056006700780089009A00AB00BC00C", 3,-1, 8,1, 0, { '\220','\011','\240','\012','\260','\013','\300','\014', '\120','\005','\140','\006','\160','\007','\200','\010', '\020','\001','\040','\002','\060','\003','\100','\004' } }, { "0x100120023003400450056006700780089009A00AB00BC00C", 3,1, 8,-1, 0, { '\004','\100','\003','\060','\002','\040','\001','\020', '\010','\200','\007','\160','\006','\140','\005','\120', '\014','\300','\013','\260','\012','\240','\011','\220' } }, { "0x100120023003400450056006700780089009A00AB00BC00C", 3,-1, 8,-1, 0, { '\014','\300','\013','\260','\012','\240','\011','\220', '\010','\200','\007','\160','\006','\140','\005','\120', '\004','\100','\003','\060','\002','\040','\001','\020' } }, { "0x155555555555555555555555", 3,1, 4,1, 1, { '\325','\125','\125','\125', '\252','\252','\252','\252', '\325','\125','\125','\125' } }, { "0x155555555555555555555555", 3,-1, 4,1, 1, { '\325','\125','\125','\125', '\252','\252','\252','\252', '\325','\125','\125','\125' } }, { "0x155555555555555555555555", 3,1, 4,-1, 1, { '\125','\125','\125','\325', '\252','\252','\252','\252', '\125','\125','\125','\325' } }, { "0x155555555555555555555555", 3,-1, 4,-1, 1, { '\125','\125','\125','\325', '\252','\252','\252','\252', '\125','\125','\125','\325' } }, }; char buf[sizeof(data[0].src) + sizeof (mp_limb_t)]; char *src; size_t align; int i; mpz_t got, want; mpz_init (got); mpz_init (want); for (i = 0; i < numberof (data); i++) { for (align = 0; align < sizeof (mp_limb_t); align++) { mpz_set_str_or_abort (want, data[i].want, 0); src = buf + align; memcpy (src, data[i].src, data[i].count * data[i].size); mpz_set_ui (got, 0L); mpz_import (got, data[i].count, data[i].order, data[i].size, data[i].endian, data[i].nail, src); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("wrong at data[%d]\n", i); printf (" count=%lu order=%d size=%lu endian=%d nail=%u align=%lu\n", (unsigned long) data[i].count, data[i].order, (unsigned long) data[i].size, data[i].endian, data[i].nail, (unsigned long) align); mpz_trace (" got ", got); mpz_trace (" want", want); abort (); } } } mpz_clear (got); mpz_clear (want); }