tset_sj.c revision 1.1.1.5 1 /* Test file for
2 mpfr_set_sj, mpfr_set_uj, mpfr_set_sj_2exp and mpfr_set_uj_2exp.
3
4 Copyright 2004, 2006-2020 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6
7 This file is part of the GNU MPFR Library.
8
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24 #define MPFR_NEED_INTMAX_H
25 #include "mpfr-test.h"
26
27 #ifndef _MPFR_H_HAVE_INTMAX_T
28
29 int
30 main (void)
31 {
32 return 77;
33 }
34
35 #else
36
37 #define PRINT_ERROR(str) \
38 do { printf ("Error for %s\n", str); exit (1); } while (0)
39
40 static int
41 inexact_sign (int x)
42 {
43 return (x < 0) ? -1 : (x > 0);
44 }
45
46 static void
47 check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N)
48 {
49 mpfr_t x, y;
50 mpfr_prec_t p;
51 int inex1, inex2, n;
52 mp_limb_t limb;
53
54 mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0);
55
56 for (p = pmin ; p < pmax ; p++)
57 {
58 mpfr_set_prec (x, p);
59 mpfr_set_prec (y, p);
60 for (n = 0 ; n < N ; n++)
61 {
62 /* mp_limb_t may be unsigned long long */
63 limb = (unsigned long) randlimb ();
64 inex1 = mpfr_set_uj (x, limb, MPFR_RNDN);
65 inex2 = mpfr_set_ui (y, limb, MPFR_RNDN);
66 if (mpfr_cmp (x, y))
67 {
68 printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n",
69 (unsigned long) limb, (unsigned long) p);
70 printf ("X="); mpfr_dump (x);
71 printf ("Y="); mpfr_dump (y);
72 exit (1);
73 }
74 if (inexact_sign (inex1) != inexact_sign (inex2))
75 {
76 printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n"
77 "Inexact1= %d Inexact2= %d\n",
78 (unsigned long) limb, (unsigned long) p, inex1, inex2);
79 exit (1);
80 }
81 }
82 }
83 /* Special case */
84 mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT);
85 inex1 = mpfr_set_uj (x, UINTMAX_MAX, MPFR_RNDN);
86 if (inex1 != 0 || mpfr_sgn(x) <= 0)
87 PRINT_ERROR ("inexact / UINTMAX_MAX");
88 inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN);
89 if (inex1 != 0 || !mpfr_powerof2_raw (x)
90 || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
91 PRINT_ERROR ("power of 2");
92 mpfr_set_uj (x, 0, MPFR_RNDN);
93 if (!MPFR_IS_ZERO (x))
94 PRINT_ERROR ("Setting 0");
95
96 mpfr_clears (x, y, (mpfr_ptr) 0);
97 }
98
99 static void
100 check_set_uj_2exp (void)
101 {
102 mpfr_t x;
103 int inex;
104
105 mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);
106
107 inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN);
108 if (inex || mpfr_cmp_ui(x, 1))
109 PRINT_ERROR ("(1U,0)");
110
111 inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN);
112 if (inex || mpfr_cmp_ui(x, 1))
113 PRINT_ERROR ("(1024U,-10)");
114
115 inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN);
116 if (inex || mpfr_cmp_ui(x, 1024L * 1024L))
117 PRINT_ERROR ("(1024U,+10)");
118
119 inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, 1000, MPFR_RNDN);
120 inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN);
121 inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN);
122 if (inex || !mpfr_powerof2_raw (x)
123 || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
124 PRINT_ERROR ("(UINTMAX_MAX)");
125
126 inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN);
127 if (inex == 0 || !mpfr_inf_p (x))
128 PRINT_ERROR ("Overflow");
129
130 inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN);
131 if (inex == 0 || !MPFR_IS_ZERO (x))
132 PRINT_ERROR ("Underflow");
133
134 mpfr_clear (x);
135 }
136
137 static void
138 check_set_sj (void)
139 {
140 mpfr_t x;
141 int inex;
142
143 mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
144
145 inex = mpfr_set_sj (x, -INTMAX_MAX, MPFR_RNDN);
146 inex |= mpfr_add_si (x, x, -1, MPFR_RNDN);
147 if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
148 || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT)
149 PRINT_ERROR ("set_sj (-INTMAX_MAX)");
150
151 inex = mpfr_set_sj (x, 1742, MPFR_RNDN);
152 if (inex || mpfr_cmp_ui (x, 1742))
153 PRINT_ERROR ("set_sj (1742)");
154
155 mpfr_clear (x);
156 }
157
158 static void
159 check_set_sj_2exp (void)
160 {
161 mpfr_t x;
162 int inex;
163
164 mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
165
166 inex = mpfr_set_sj_2exp (x, INTMAX_MIN, 1000, MPFR_RNDN);
167 if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
168 || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT + 1000)
169 PRINT_ERROR ("set_sj_2exp (INTMAX_MIN)");
170
171 mpfr_clear (x);
172 }
173
174 #define REXP 1024
175
176 static void
177 test_2exp_extreme_aux (void)
178 {
179 mpfr_t x1, x2, y;
180 mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
181 { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
182 mpfr_flags_t flags1, flags2;
183 int i, j, rnd, inex1, inex2;
184 char s;
185
186 ep[0] = MPFR_EXP_MIN;
187 for (i = 0; i < numberof(eb); i++)
188 for (j = 0; j < 8; j++)
189 ep[1 + 8 * i + j] = eb[i] - j;
190
191 mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
192 mpfr_init2 (y, 32);
193
194 /* The cast to int is needed if numberof(ep) is of unsigned type, in
195 which case the condition without the cast would be always false. */
196 for (i = -2; i < (int) numberof(ep); i++)
197 for (j = -31; j <= 31; j++)
198 RND_LOOP_NO_RNDF (rnd)
199 {
200 int sign = j < 0 ? -1 : 1;
201 intmax_t em;
202
203 if (i < 0)
204 {
205 em = i == -2 ? INTMAX_MIN : INTMAX_MAX;
206 mpfr_clear_flags ();
207 inex1 = j == 0 ?
208 (mpfr_set_zero (x1, +1), 0) : i == -2 ?
209 mpfr_underflow (x1, rnd == MPFR_RNDN ?
210 MPFR_RNDZ : (mpfr_rnd_t) rnd, sign) :
211 mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
212 flags1 = __gmpfr_flags;
213 }
214 else
215 {
216 em = ep[i];
217 /* Compute the expected value, inex and flags */
218 inex1 = mpfr_set_si (y, j, MPFR_RNDN);
219 MPFR_ASSERTN (inex1 == 0);
220 inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
221 /* x1 is the rounded value and inex1 the ternary value,
222 assuming that the exponent argument is 0 (this is the
223 rounded significand of the final result, assuming an
224 unbounded exponent range). The multiplication by a
225 power of 2 is exact, unless underflow/overflow occurs.
226 The tests on the exponent below avoid integer overflows
227 (ep[i] may take extreme values). */
228 e = mpfr_get_exp (x1);
229 mpfr_clear_flags ();
230 if (j != 0 && ep[i] < __gmpfr_emin - e) /* underflow */
231 {
232 mpfr_rnd_t r =
233 (rnd == MPFR_RNDN &&
234 (ep[i] < __gmpfr_emin - mpfr_get_exp (y) - 1 ||
235 IS_POW2 (sign * j))) ?
236 MPFR_RNDZ : (mpfr_rnd_t) rnd;
237 inex1 = mpfr_underflow (x1, r, sign);
238 flags1 = __gmpfr_flags;
239 }
240 else if (j != 0 && ep[i] > __gmpfr_emax - e) /* overflow */
241 {
242 inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
243 flags1 = __gmpfr_flags;
244 }
245 else
246 {
247 if (j != 0)
248 mpfr_set_exp (x1, ep[i] + e);
249 flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
250 }
251 }
252
253 /* Test mpfr_set_sj_2exp */
254 mpfr_clear_flags ();
255 inex2 = mpfr_set_sj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
256 flags2 = __gmpfr_flags;
257
258 if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
259 mpfr_equal_p (x1, x2)))
260 {
261 s = 's';
262 goto err_extreme;
263 }
264
265 if (j < 0)
266 continue;
267
268 /* Test mpfr_set_uj_2exp */
269 mpfr_clear_flags ();
270 inex2 = mpfr_set_uj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
271 flags2 = __gmpfr_flags;
272
273 if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
274 mpfr_equal_p (x1, x2)))
275 {
276 s = 'u';
277 err_extreme:
278 printf ("Error in extreme mpfr_set_%cj_2exp for i=%d j=%d %s\n",
279 s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
280 printf ("emin=%" MPFR_EXP_FSPEC "d "
281 "emax=%" MPFR_EXP_FSPEC "d\n",
282 (mpfr_eexp_t) __gmpfr_emin,
283 (mpfr_eexp_t) __gmpfr_emax);
284 #ifndef NPRINTF_J
285 printf ("e = %jd\n", em);
286 #endif
287 printf ("Expected ");
288 mpfr_dump (x1);
289 printf ("with inex = %d and flags =", inex1);
290 flags_out (flags1);
291 printf ("Got ");
292 mpfr_dump (x2);
293 printf ("with inex = %d and flags =", inex2);
294 flags_out (flags2);
295 exit (1);
296 }
297 }
298
299 mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
300 }
301
302 static void
303 test_2exp_extreme (void)
304 {
305 mpfr_exp_t emin, emax;
306
307 emin = mpfr_get_emin ();
308 emax = mpfr_get_emax ();
309
310 set_emin (MPFR_EMIN_MIN);
311 set_emax (MPFR_EMAX_MAX);
312 test_2exp_extreme_aux ();
313
314 set_emin (-REXP);
315 set_emax (REXP);
316 test_2exp_extreme_aux ();
317
318 set_emin (emin);
319 set_emax (emax);
320 }
321
322 int
323 main (int argc, char *argv[])
324 {
325 tests_start_mpfr ();
326
327 check_set_uj (2, 128, 50);
328 check_set_uj_2exp ();
329 check_set_sj ();
330 check_set_sj_2exp ();
331 test_2exp_extreme ();
332
333 tests_end_mpfr ();
334 return 0;
335 }
336
337 #endif
338