1 /* Test mpz_get_d_2exp.
3 Copyright 2002, 2003 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/. */
30 static const unsigned long data[] = {
31 1, 32, 52, 53, 54, 63, 64, 65, 128, 256, 511, 512, 513
35 long got_exp, want_exp;
40 for (i = 0; i < numberof (data); i++)
43 mpz_mul_2exp (z, z, data[i]);
45 want_exp = data[i] + 1;
46 got = mpz_get_d_2exp (&got_exp, z);
47 if (got != want || got_exp != want_exp)
49 printf ("mpz_get_d_2exp wrong on 2**%ld\n", data[i]);
51 d_trace (" want ", want);
52 d_trace (" got ", got);
53 printf (" want exp %ld\n", want_exp);
54 printf (" got exp %ld\n", got_exp);
59 mpz_mul_2exp (z, z, data[i]);
61 want_exp = data[i] + 1;
62 got = mpz_get_d_2exp (&got_exp, z);
63 if (got != want || got_exp != want_exp)
65 printf ("mpz_get_d_2exp wrong on -2**%ld\n", data[i]);
67 d_trace (" want ", want);
68 d_trace (" got ", got);
69 printf (" want exp %ld\n", want_exp);
70 printf (" got exp %ld\n", got_exp);
77 /* Check that hardware rounding doesn't make mpz_get_d_2exp return a value
78 outside its defined range. */
82 static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 };
86 int i, rnd_mode, old_rnd_mode;
89 old_rnd_mode = tests_hardware_getround ();
91 for (rnd_mode = 0; rnd_mode < 4; rnd_mode++)
93 tests_hardware_setround (rnd_mode);
95 for (i = 0; i < numberof (data); i++)
98 mpz_mul_2exp (z, z, data[i]);
99 mpz_sub_ui (z, z, 1L);
101 got = mpz_get_d_2exp (&got_exp, z);
102 if (got < 0.5 || got >= 1.0)
104 printf ("mpz_get_d_2exp wrong on 2**%lu-1\n", data[i]);
105 printf ("result out of range, expect 0.5 <= got < 1.0\n");
106 printf (" rnd_mode = %d\n", rnd_mode);
107 printf (" data[i] = %lu\n", data[i]);
108 mpz_trace (" z ", z);
109 d_trace (" got ", got);
110 printf (" got exp %ld\n", got_exp);
115 got = mpz_get_d_2exp (&got_exp, z);
116 if (got <= -1.0 || got > -0.5)
118 printf ("mpz_get_d_2exp wrong on -2**%lu-1\n", data[i]);
119 printf ("result out of range, expect -1.0 < got <= -0.5\n");
120 printf (" rnd_mode = %d\n", rnd_mode);
121 printf (" data[i] = %lu\n", data[i]);
122 mpz_trace (" z ", z);
123 d_trace (" got ", got);
124 printf (" got exp %ld\n", got_exp);
131 tests_hardware_setround (old_rnd_mode);
137 gmp_randstate_ptr rands = RANDS;
146 for (i = 0; i < 200; i++)
148 bits = gmp_urandomm_ui (rands, 512L);
149 mpz_urandomb (z, rands, bits);
151 got = mpz_get_d_2exp (&got_exp, z);
152 if (mpz_sgn (z) == 0)
154 bits = mpz_sizeinbase (z, 2);
156 if (got < 0.5 || got >= 1.0)
158 printf ("mpz_get_d_2exp out of range, expect 0.5 <= got < 1.0\n");
159 mpz_trace (" z ", z);
160 d_trace (" got ", got);
161 printf (" got exp %ld\n", got_exp);
165 /* FIXME: If mpz_get_d_2exp rounds upwards we might have got_exp ==
166 bits+1, so leave this test disabled until we decide if that's what
167 should happen, or not. */
171 printf ("mpz_get_d_2exp wrong exponent\n", i);
172 mpz_trace (" z ", z);
173 d_trace (" bits ", bits);
174 d_trace (" got ", got);
175 printf (" got exp %ld\n", got_exp);