3 Copyright 2002, 2003, 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/. */
20 /* Note that we don't use <limits.h> for LONG_MIN, but instead our own
21 definition in gmp-impl.h. In gcc 2.95.4 (debian 3.0) under
22 -mcpu=ultrasparc, limits.h sees __sparc_v9__ defined and assumes that
23 means long is 64-bit long, but it's only 32-bits, causing fatal compile
38 #ifndef _GMP_IEEE_FLOATS
39 #define _GMP_IEEE_FLOATS 0
43 /* Exercise various 2^n values, with various exponents and positive and
48 static const int bit_table[] = {
50 GMP_NUMB_BITS - 2, GMP_NUMB_BITS - 1,
52 GMP_NUMB_BITS + 1, GMP_NUMB_BITS + 2,
53 2 * GMP_NUMB_BITS - 2, 2 * GMP_NUMB_BITS - 1,
55 2 * GMP_NUMB_BITS + 1, 2 * GMP_NUMB_BITS + 2,
56 3 * GMP_NUMB_BITS - 2, 3 * GMP_NUMB_BITS - 1,
58 3 * GMP_NUMB_BITS + 1, 3 * GMP_NUMB_BITS + 2,
59 4 * GMP_NUMB_BITS - 2, 4 * GMP_NUMB_BITS - 1,
61 4 * GMP_NUMB_BITS + 1, 4 * GMP_NUMB_BITS + 2,
62 5 * GMP_NUMB_BITS - 2, 5 * GMP_NUMB_BITS - 1,
64 5 * GMP_NUMB_BITS + 1, 5 * GMP_NUMB_BITS + 2,
65 6 * GMP_NUMB_BITS - 2, 6 * GMP_NUMB_BITS - 1,
67 6 * GMP_NUMB_BITS + 1, 6 * GMP_NUMB_BITS + 2,
69 static const int exp_table[] = {
70 0, -100, -10, -1, 1, 10, 100,
73 /* FIXME: It'd be better to base this on the float format. */
75 int limit = 127; /* vax fp numbers have limited range */
82 mp_size_t nsize, sign;
83 long bit, exp, want_bit;
86 for (bit_i = 0; bit_i < numberof (bit_table); bit_i++)
88 bit = bit_table[bit_i];
90 nsize = BITS_TO_LIMBS (bit+1);
91 refmpn_zero (np, nsize);
92 np[bit/GMP_NUMB_BITS] = CNST_LIMB(1) << (bit % GMP_NUMB_BITS);
94 for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
96 exp = exp_table[exp_i];
99 if (want_bit > limit || want_bit < -limit)
103 for (i = 0; i < want_bit; i++)
105 for (i = 0; i > want_bit; i--)
108 for (sign = 0; sign >= -1; sign--, want = -want)
110 got = mpn_get_d (np, nsize, sign, exp);
113 printf ("mpn_get_d wrong on 2^n\n");
114 printf (" bit %ld\n", bit);
115 printf (" exp %ld\n", exp);
116 printf (" want_bit %ld\n", want_bit);
117 printf (" sign %ld\n", (long) sign);
118 mpn_trace (" n ", np, nsize);
119 printf (" nsize %ld\n", (long) nsize);
120 d_trace (" want ", want);
121 d_trace (" got ", got);
130 /* Exercise values 2^n+1, while such a value fits the mantissa of a double. */
136 mp_size_t nsize, sign;
139 mant_bits = tests_dbl_mant_bits ();
143 np = refmpn_malloc_limbs (BITS_TO_LIMBS (mant_bits));
145 for (i = 1; i < mant_bits; i++)
147 nsize = BITS_TO_LIMBS (i+1);
148 refmpn_zero (np, nsize);
149 np[i/GMP_NUMB_BITS] = CNST_LIMB(1) << (i % GMP_NUMB_BITS);
152 for (sign = 0; sign >= -1; sign--)
154 got = mpn_get_d (np, nsize, sign, 0);
157 printf ("mpn_get_d wrong on 2^%d + 1\n", i);
158 printf (" sign %ld\n", (long) sign);
159 mpn_trace (" n ", np, nsize);
160 printf (" nsize %ld\n", (long) nsize);
161 d_trace (" want ", want);
162 d_trace (" got ", got);
168 want = 2.0 * want - 1.0;
175 /* Expect large negative exponents to underflow to 0.0.
176 Some systems might have hardware traps for such an underflow (though
177 usually it's not the default), so watch out for SIGFPE. */
179 check_underflow (void)
181 static const long exp_table[] = {
184 static const mp_limb_t np[1] = { 1 };
187 mp_size_t nsize, sign;
191 nsize = numberof (np);
193 if (tests_setjmp_sigfpe() == 0)
195 for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
197 exp = exp_table[exp_i];
199 for (sign = 0; sign >= -1; sign--)
201 got = mpn_get_d (np, nsize, sign, exp);
204 printf ("mpn_get_d wrong, didn't get 0.0 on underflow\n");
205 printf (" nsize %ld\n", (long) nsize);
206 printf (" exp %ld\n", exp);
207 printf (" sign %ld\n", (long) sign);
208 d_trace (" got ", got);
216 printf ("Warning, underflow to zero tests skipped due to SIGFPE (exp=%ld)\n", exp);
218 tests_sigfpe_done ();
222 /* Expect large values to result in +/-inf, on IEEE systems. */
226 static const long exp_table[] = {
229 static const mp_limb_t np[4] = { 1, 1, 1, 1 };
231 mp_size_t nsize, sign, got_sign;
235 if (! _GMP_IEEE_FLOATS)
238 for (nsize = 1; nsize <= numberof (np); nsize++)
240 for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
242 exp = exp_table[exp_i];
244 for (sign = 0; sign >= -1; sign--)
246 got = mpn_get_d (np, nsize, sign, exp);
247 got_sign = (got >= 0 ? 0 : -1);
248 if (! tests_isinf (got))
250 printf ("mpn_get_d wrong, didn't get infinity\n");
252 printf (" nsize %ld\n", (long) nsize);
253 printf (" exp %ld\n", exp);
254 printf (" sign %ld\n", (long) sign);
255 d_trace (" got ", got);
256 printf (" got sign %ld\n", (long) got_sign);
259 if (got_sign != sign)
261 printf ("mpn_get_d wrong sign on infinity\n");
269 /* Check values 2^n approaching and into IEEE denorm range.
270 Some systems might not support denorms, or might have traps setup, so
271 watch out for SIGFPE. */
273 check_ieee_denorm (void)
281 if (! _GMP_IEEE_FLOATS)
284 if (tests_setjmp_sigfpe() == 0)
288 for (i = 0; i > exp; i--)
291 for ( ; exp > -1500 && want != 0.0; exp--)
293 for (sign = 0; sign >= -1; sign--)
295 got = mpn_get_d (&n, (mp_size_t) 1, sign, exp);
298 printf ("mpn_get_d wrong on denorm\n");
300 printf (" exp %ld\n", exp);
301 printf (" sign %ld\n", (long) sign);
302 d_trace (" got ", got);
303 d_trace (" want ", want);
314 printf ("Warning, IEEE denorm tests skipped due to SIGFPE (exp=%ld)\n", exp);
316 tests_sigfpe_done ();
320 /* Check values 2^n approaching exponent overflow.
321 Some systems might trap on overflow, so watch out for SIGFPE. */
323 check_ieee_overflow (void)
331 if (! _GMP_IEEE_FLOATS)
334 if (tests_setjmp_sigfpe() == 0)
338 for (i = 0; i < exp; i++)
341 for ( ; exp < 1050; exp++)
343 for (sign = 0; sign >= -1; sign--)
345 got = mpn_get_d (&n, (mp_size_t) 1, sign, exp);
348 printf ("mpn_get_d wrong on overflow\n");
350 printf (" exp %ld\n", exp);
351 printf (" sign %ld\n", (long) sign);
352 d_trace (" got ", got);
353 d_trace (" want ", want);
364 printf ("Warning, IEEE overflow tests skipped due to SIGFPE (exp=%ld)\n", exp);
366 tests_sigfpe_done ();
370 /* ARM gcc 2.95.4 was seen generating bad code for ulong->double
371 conversions, resulting in for instance 0x81c25113 incorrectly converted.
372 This test exercises that value, to see mpn_get_d has avoided the
375 check_0x81c25113 (void)
377 #if GMP_NUMB_BITS >= 32
378 double want = 2176995603.0;
384 if (tests_dbl_mant_bits() < 32)
387 for (nsize = 1; nsize <= numberof (np); nsize++)
389 refmpn_zero (np, nsize-1);
390 np[nsize-1] = CNST_LIMB(0x81c25113);
391 exp = - (nsize-1) * GMP_NUMB_BITS;
392 got = mpn_get_d (np, nsize, (mp_size_t) 0, exp);
395 printf ("mpn_get_d wrong on 2176995603 (0x81c25113)\n");
396 printf (" nsize %ld\n", (long) nsize);
397 printf (" exp %ld\n", exp);
398 d_trace (" got ", got);
399 d_trace (" want ", want);
410 gmp_randstate_ptr rands = RANDS;
412 unsigned long mant_bits;
413 long exp, exp_min, exp_max;
415 mp_size_t nalloc, nsize, sign;
416 mp_limb_t nhigh_mask;
419 mant_bits = tests_dbl_mant_bits ();
423 /* Allow for vax D format with exponent 127 to -128 only.
424 FIXME: Do something to probe for a valid exponent range. */
425 exp_min = -100 - mant_bits;
426 exp_max = 100 - mant_bits;
428 /* space for mant_bits */
429 nalloc = BITS_TO_LIMBS (mant_bits);
430 np = refmpn_malloc_limbs (nalloc);
431 nhigh_mask = MP_LIMB_T_MAX
432 >> (GMP_NAIL_BITS + nalloc * GMP_NUMB_BITS - mant_bits);
434 for (rep = 0; rep < 200; rep++)
436 /* random exp_min to exp_max, inclusive */
437 exp = exp_min + (long) gmp_urandomm_ui (rands, exp_max - exp_min + 1);
439 /* mant_bits worth of random at np */
441 mpn_random (np, nalloc);
443 mpn_random2 (np, nalloc);
445 np[nsize-1] &= nhigh_mask;
446 MPN_NORMALIZE (np, nsize);
450 sign = (mp_size_t) gmp_urandomb_ui (rands, 1L) - 1;
452 /* want = {np,nsize}, converting one bit at a time */
454 for (i = 0, d = 1.0; i < mant_bits; i++, d *= 2.0)
455 if (np[i/GMP_NUMB_BITS] & (CNST_LIMB(1) << (i%GMP_NUMB_BITS)))
460 /* want = want * 2^exp */
461 for (i = 0; i < exp; i++)
463 for (i = 0; i > exp; i--)
466 got = mpn_get_d (np, nsize, sign, exp);
470 printf ("mpn_get_d wrong on random data\n");
471 printf (" sign %ld\n", (long) sign);
472 mpn_trace (" n ", np, nsize);
473 printf (" nsize %ld\n", (long) nsize);
474 printf (" exp %ld\n", exp);
475 d_trace (" want ", want);
476 d_trace (" got ", got);
495 check_ieee_denorm ();
496 check_ieee_overflow ();