1 /* Test mpq_get_d and mpq_set_d
3 Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2002, 2003 Free Software
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
32 /* VAX D floats only have an 8 bit signed exponent, so anything 2^128 or
33 bigger will overflow, that being 4 limbs. */
34 #if defined (__vax__) && SIZE > 4
42 void dump __GMP_PROTO ((mpq_t));
45 check_monotonic (int argc, char **argv)
52 mpq_t qlast_d, qnew_d;
56 reps = atoi (argv[1]);
58 /* The idea here is to test the monotonousness of mpq_get_d by adding
59 numbers to the numerator and denominator. */
66 for (i = 0; i < reps; i++)
68 size = urandom () % SIZE - SIZE/2;
69 mpz_random2 (mpq_numref (a), size);
72 size = urandom () % SIZE - SIZE/2;
73 mpz_random2 (mpq_denref (a), size);
75 while (mpz_cmp_ui (mpq_denref (a), 0) == 0);
79 last_d = mpq_get_d (a);
80 mpq_set_d (qlast_d, last_d);
81 for (j = 0; j < 10; j++)
83 size = urandom () % EPSIZE + 1;
84 mpz_random2 (mpq_numref (eps), size);
85 size = urandom () % EPSIZE + 1;
86 mpz_random2 (mpq_denref (eps), size);
87 mpq_canonicalize (eps);
91 new_d = mpq_get_d (a);
94 printf ("\nERROR (test %d/%d): bad mpq_get_d results\n", i, j);
95 printf ("last: %.16g\n", last_d);
96 printf (" new: %.16g\n", new_d); dump (a);
99 mpq_set_d (qnew_d, new_d);
100 MPQ_CHECK_FORMAT (qnew_d);
101 if (mpq_cmp (qlast_d, qnew_d) > 0)
103 printf ("ERROR (test %d/%d): bad mpq_set_d results\n", i, j);
104 printf ("last: %.16g\n", last_d); dump (qlast_d);
105 printf (" new: %.16g\n", new_d); dump (qnew_d);
109 mpq_set (qlast_d, qnew_d);
120 my_ldexp (double d, int e)
157 check_random (int argc, char **argv)
159 double d, d2, nd, dd;
161 mp_limb_t rp[LIMBS_PER_DOUBLE + 1];
162 int test, reps = 100000;
166 reps = 100 * atoi (argv[1]);
170 for (test = 0; test < reps; test++)
172 mpn_random2 (rp, LIMBS_PER_DOUBLE + 1);
174 for (i = LIMBS_PER_DOUBLE - 1; i >= 0; i--)
175 d = d * MP_BASE_AS_DOUBLE + rp[i];
176 d = my_ldexp (d, (int) (rp[LIMBS_PER_DOUBLE] % 1000) - 500);
178 nd = mpz_get_d (mpq_numref (q));
179 dd = mpz_get_d (mpq_denref (q));
183 printf ("ERROR (check_random test %d): bad mpq_set_d results\n", test);
184 printf ("%.16g\n", d);
185 printf ("%.16g\n", d2);
195 mpz_out_str (stdout, 10, mpq_numref (x));
197 mpz_out_str (stdout, 10, mpq_denref (x));
201 /* Check various values 2^n and 1/2^n. */
205 static const long data[] = {
206 -3*GMP_NUMB_BITS-1, -3*GMP_NUMB_BITS, -3*GMP_NUMB_BITS+1,
207 -2*GMP_NUMB_BITS-1, -2*GMP_NUMB_BITS, -2*GMP_NUMB_BITS+1,
208 -GMP_NUMB_BITS-1, -GMP_NUMB_BITS, -GMP_NUMB_BITS+1,
209 -5, -2, -1, 0, 1, 2, 5,
210 GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
211 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
212 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1,
222 for (i = 0; i < numberof (data); i++)
226 mpq_set_ui (q, 1L, 1L);
228 mpq_mul_2exp (q, q, exp);
230 mpq_div_2exp (q, q, -exp);
233 for (l = 0; l < exp; l++)
235 for (l = 0; l > exp; l--)
238 for (neg = 0; neg <= 1; neg++)
250 printf ("mpq_get_d wrong on %s2**%ld\n", neg ? "-" : "", exp);
251 mpq_trace (" q ", q);
252 d_trace (" want ", want);
253 d_trace (" got ", got);
262 main (int argc, char **argv)
267 check_monotonic (argc, argv);
268 check_random (argc, argv);