1 /* Test mpz_[cft]div_[qr]_2exp.
3 Copyright 2001 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
28 /* If the remainder is in the correct range and q*d+r is correct, then q
29 must have rounded correctly. */
32 check_one (mpz_srcptr a, unsigned long d)
42 mpz_set_ui (d2exp, 1L);
43 mpz_mul_2exp (d2exp, d2exp, d);
45 #define INPLACE(fun,dst,src,d) \
54 for (inplace = 0; inplace <= 1; inplace++)
56 INPLACE (mpz_fdiv_q_2exp, q, a, d);
57 INPLACE (mpz_fdiv_r_2exp, r, a, d);
59 mpz_mul_2exp (p, q, d);
61 if (mpz_sgn (r) < 0 || mpz_cmp (r, d2exp) >= 0)
63 printf ("mpz_fdiv_r_2exp result out of range\n");
66 if (mpz_cmp (p, a) != 0)
68 printf ("mpz_fdiv_[qr]_2exp doesn't multiply back\n");
73 INPLACE (mpz_cdiv_q_2exp, q, a, d);
74 INPLACE (mpz_cdiv_r_2exp, r, a, d);
76 mpz_mul_2exp (p, q, d);
78 if (mpz_sgn (r) > 0 || mpz_cmpabs (r, d2exp) >= 0)
80 printf ("mpz_cdiv_r_2exp result out of range\n");
83 if (mpz_cmp (p, a) != 0)
85 printf ("mpz_cdiv_[qr]_2exp doesn't multiply back\n");
90 INPLACE (mpz_tdiv_q_2exp, q, a, d);
91 INPLACE (mpz_tdiv_r_2exp, r, a, d);
93 mpz_mul_2exp (p, q, d);
95 if (mpz_sgn (r) != 0 && mpz_sgn (r) != mpz_sgn (a))
97 printf ("mpz_tdiv_r_2exp result wrong sign\n");
100 if (mpz_cmpabs (r, d2exp) >= 0)
102 printf ("mpz_tdiv_r_2exp result out of range\n");
105 if (mpz_cmp (p, a) != 0)
107 printf ("mpz_tdiv_[qr]_2exp doesn't multiply back\n");
121 printf ("d=%lu\n", d);
128 printf ("d=0x%lX\n", d);
138 check_all (mpz_ptr a, unsigned long d)
149 static const unsigned long table[] = {
151 GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
152 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
153 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1,
154 4*GMP_NUMB_BITS-1, 4*GMP_NUMB_BITS, 4*GMP_NUMB_BITS+1
163 /* a==0, and various d */
165 for (i = 0; i < numberof (table); i++)
166 check_one (a, table[i]);
168 /* a==2^n, and various d */
169 for (i = 0; i < numberof (table); i++)
173 mpz_mul_2exp (a, a, n);
175 for (j = 0; j < numberof (table); j++)
187 check_random (int argc, char *argv[])
189 gmp_randstate_ptr rands = RANDS;
196 reps = atoi (argv[1]);
200 for (i = 0; i < reps; i++)
202 /* exponentially within 2 to 257 bits */
203 mpz_erandomb (a, rands, urandom () % 8 + 2);
205 d = urandom () % 256;
215 main (int argc, char *argv[])
220 check_random (argc, argv);