3 Copyright 1996, 2001, 2004 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/. */
32 check_rand (int argc, char **argv)
39 mp_size_t bprec = 100;
40 mpf_t rerr, max_rerr, limit_rerr;
44 reps = strtol (argv[1], 0, 0);
46 bprec = strtol (argv[2], 0, 0);
49 mpf_set_default_prec (bprec);
51 mpf_init_set_ui (limit_rerr, 1);
52 mpf_div_2exp (limit_rerr, limit_rerr, bprec);
54 mpf_dump (limit_rerr);
57 mpf_init_set_ui (max_rerr, 0);
63 for (i = 0; i < reps; i++)
65 size = urandom () % (2 * SIZE) - SIZE;
66 exp = urandom () % SIZE;
67 mpf_random2 (u, size, exp);
69 size = urandom () % (2 * SIZE) - SIZE;
70 exp = urandom () % SIZE;
71 mpf_random2 (v, size, exp);
73 if ((urandom () & 1) != 0)
75 else if ((urandom () & 1) != 0)
79 refmpf_sub (wref, u, v);
81 mpf_reldiff (rerr, w, wref);
82 if (mpf_cmp (rerr, max_rerr) > 0)
84 mpf_set (max_rerr, rerr);
88 if (mpf_cmp (rerr, limit_rerr) > 0)
90 printf ("ERROR after %d tests\n", i);
91 printf (" u = "); mpf_dump (u);
92 printf (" v = "); mpf_dump (v);
93 printf ("wref = "); mpf_dump (wref);
94 printf (" w = "); mpf_dump (w);
100 mpf_clear (limit_rerr);
102 mpf_clear (max_rerr);
114 static const struct {
121 { { 123, 2, { 8, 9 } }, { 123, 1, { 9 } }, { 122, 1, { 8 } } },
123 /* f - f == 0, various sizes.
124 These exercise a past problem (gmp 4.1.3 and earlier) where the
125 result exponent was not zeroed on a zero result like this. */
126 { { 0, 0 }, { 0, 0 }, { 0, 0 } },
127 { { 99, 1, { 1 } }, { 99, 1, { 1 } }, { 0, 0 } },
128 { { 99, 2, { 123, 456 } }, { 99, 2, { 123, 456 } }, { 0, 0 } },
129 { { 99, 3, { 123, 456, 789 } }, { 99, 3, { 123, 456, 789 } }, { 0, 0 } },
131 /* High limbs cancel, leaving just the low limbs of the longer operand.
132 This exercises a past problem (gmp 4.1.3 and earlier) where high zero
133 limbs on the remainder were not stripped before truncating to the
134 destination, causing loss of precision. */
135 { { 123, 2, { 8, 9 } }, { 123, 1, { 9 } }, { 122, 1, { 8 } } },
136 { { 123, 3, { 8, 0, 9 } }, { 123, 1, { 9 } }, { 121, 1, { 8 } } },
137 { { 123, 4, { 8, 0, 0, 9 } }, { 123, 1, { 9 } }, { 120, 1, { 8 } } },
138 { { 123, 5, { 8, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 119, 1, { 8 } } },
139 { { 123, 6, { 8, 0, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 118, 1, { 8 } } },
143 mpf_t x, y, got, want;
149 for (i = 0; i < numberof (data); i++)
151 for (swap = 0; swap <= 1; swap++)
153 PTR(x) = (mp_ptr) data[i].x.d;
154 SIZ(x) = data[i].x.size;
155 EXP(x) = data[i].x.exp;
156 PREC(x) = numberof (data[i].x.d);
157 MPF_CHECK_FORMAT (x);
159 PTR(y) = (mp_ptr) data[i].y.d;
160 SIZ(y) = data[i].y.size;
161 EXP(y) = data[i].y.exp;
162 PREC(y) = numberof (data[i].y.d);
163 MPF_CHECK_FORMAT (y);
165 PTR(want) = (mp_ptr) data[i].want.d;
166 SIZ(want) = data[i].want.size;
167 EXP(want) = data[i].want.exp;
168 PREC(want) = numberof (data[i].want.d);
169 MPF_CHECK_FORMAT (want);
174 SIZ(want) = - SIZ(want);
178 /* MPF_CHECK_FORMAT (got); */
180 if (mpf_cmp (got, want) != 0)
182 printf ("check_data() wrong reault at data[%d] (operands%s swapped)\n", i, swap ? "" : " not");
185 mpf_trace ("got ", got);
186 mpf_trace ("want", want);
197 main (int argc, char **argv)
202 check_rand (argc, argv);