Annotation of OpenXM_contrib/gmp/tests/mpz/t-div_2exp.c, Revision 1.1.1.1
1.1 ohara 1: /* Test mpz_[cft]div_[qr]_2exp.
2:
3: Copyright 2001 Free Software Foundation, Inc.
4:
5: This file is part of the GNU MP Library.
6:
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 2.1 of the License, or (at your
10: option) any later version.
11:
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.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include <stdio.h>
23: #include <stdlib.h>
24:
25: #include "gmp.h"
26: #include "gmp-impl.h"
27: #include "tests.h"
28:
29:
30: /* If the remainder is in the correct range and q*d+r is correct, then q
31: must have rounded correctly. */
32:
33: void
34: check_one (mpz_srcptr a, unsigned long d)
35: {
36: mpz_t q, r, p, d2exp;
37: int inplace;
38:
39: mpz_init (d2exp);
40: mpz_init (q);
41: mpz_init (r);
42: mpz_init (p);
43:
44: mpz_set_ui (d2exp, 1L);
45: mpz_mul_2exp (d2exp, d2exp, d);
46:
47: #define INPLACE(fun,dst,src,d) \
48: if (inplace) \
49: { \
50: mpz_set (dst, src); \
51: fun (dst, dst, d); \
52: } \
53: else \
54: fun (dst, src, d);
55:
56: for (inplace = 0; inplace <= 1; inplace++)
57: {
58: INPLACE (mpz_fdiv_q_2exp, q, a, d);
59: INPLACE (mpz_fdiv_r_2exp, r, a, d);
60:
61: mpz_mul_2exp (p, q, d);
62: mpz_add (p, p, r);
63: if (mpz_sgn (r) < 0 || mpz_cmp (r, d2exp) >= 0)
64: {
65: printf ("mpz_fdiv_r_2exp result out of range\n");
66: goto error;
67: }
68: if (mpz_cmp (p, a) != 0)
69: {
70: printf ("mpz_fdiv_[qr]_2exp doesn't multiply back\n");
71: goto error;
72: }
73:
74:
75: INPLACE (mpz_cdiv_q_2exp, q, a, d);
76: INPLACE (mpz_cdiv_r_2exp, r, a, d);
77:
78: mpz_mul_2exp (p, q, d);
79: mpz_add (p, p, r);
80: if (mpz_sgn (r) > 0 || mpz_cmpabs (r, d2exp) >= 0)
81: {
82: printf ("mpz_cdiv_r_2exp result out of range\n");
83: goto error;
84: }
85: if (mpz_cmp (p, a) != 0)
86: {
87: printf ("mpz_cdiv_[qr]_2exp doesn't multiply back\n");
88: goto error;
89: }
90:
91:
92: INPLACE (mpz_tdiv_q_2exp, q, a, d);
93: INPLACE (mpz_tdiv_r_2exp, r, a, d);
94:
95: mpz_mul_2exp (p, q, d);
96: mpz_add (p, p, r);
97: if (mpz_sgn (r) != 0 && mpz_sgn (r) != mpz_sgn (a))
98: {
99: printf ("mpz_tdiv_r_2exp result wrong sign\n");
100: goto error;
101: }
102: if (mpz_cmpabs (r, d2exp) >= 0)
103: {
104: printf ("mpz_tdiv_r_2exp result out of range\n");
105: goto error;
106: }
107: if (mpz_cmp (p, a) != 0)
108: {
109: printf ("mpz_tdiv_[qr]_2exp doesn't multiply back\n");
110: goto error;
111: }
112: }
113:
114: mpz_clear (d2exp);
115: mpz_clear (q);
116: mpz_clear (r);
117: mpz_clear (p);
118: return;
119:
120:
121: error:
122: mpz_trace ("a", a);
123: printf ("d=%lu\n", d);
124: mpz_trace ("q", q);
125: mpz_trace ("r", r);
126: mpz_trace ("p", p);
127:
128: mp_trace_base = -16;
129: mpz_trace ("a", a);
130: printf ("d=0x%lX\n", d);
131: mpz_trace ("q", q);
132: mpz_trace ("r", r);
133: mpz_trace ("p", p);
134:
135: abort ();
136: }
137:
138:
139: void
140: check_all (mpz_ptr a, unsigned long d)
141: {
142: check_one (a, d);
143: mpz_neg (a, a);
144: check_one (a, d);
145: }
146:
147:
148: void
149: check_various (void)
150: {
151: unsigned long i, d;
152: mpz_t a;
153:
154: mpz_init (a);
155:
156: /* a==0, and various d */
157: mpz_set_ui (a, 0L);
158: for (d = 0; d < 2*BITS_PER_MP_LIMB+4; d++)
159: check_one (a, d);
160:
161: /* a==2^i, and various d */
162: for (i = 0; i < 5*BITS_PER_MP_LIMB; i++)
163: {
164: d = (i < BITS_PER_MP_LIMB+3 ? 0 : i-(BITS_PER_MP_LIMB+3));
165: for ( ; d < i+BITS_PER_MP_LIMB+3; d++)
166: {
167: mpz_set_ui (a, 1L);
168: mpz_mul_2exp (a, a, i);
169: check_all (a, d);
170: }
171: }
172:
173: mpz_clear (a);
174: }
175:
176:
177: void
178: check_random (int argc, char *argv[])
179: {
180: gmp_randstate_ptr rands = RANDS;
181: int reps = 5000;
182: mpz_t a;
183: unsigned long d;
184: int i;
185:
186: if (argc == 2)
187: reps = atoi (argv[1]);
188:
189: mpz_init (a);
190:
191: for (i = 0; i < reps; i++)
192: {
193: /* exponentially within 2 to 257 bits */
194: mpz_erandomb (a, rands, urandom () % 8 + 2);
195:
196: d = urandom () % 256;
197:
198: check_all (a, d);
199: }
200:
201: mpz_clear (a);
202: }
203:
204:
205: int
206: main (int argc, char *argv[])
207: {
208: tests_start ();
209:
210: check_various ();
211: check_random (argc, argv);
212:
213: tests_end ();
214: exit (0);
215: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>