1 /* Test file for mpfr_set_float128 and mpfr_get_float128.
2
3 Copyright 2012-2023 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba projects, INRIA.
5
6 This file is part of the GNU MPFR Library.
7
8 The GNU MPFR 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.
12
13 The GNU MPFR 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.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23 /* Needed due to the test on MPFR_WANT_FLOAT128 */
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #ifdef MPFR_WANT_FLOAT128
29
30 #include "mpfr-test.h"
31 #include "ieee_floats.h"
32
33 static void
check_special(void)34 check_special (void)
35 {
36 _Float128 f;
37 mpfr_t x;
38
39 mpfr_init2 (x, 113);
40
41 #if !defined(MPFR_ERRDIVZERO)
42 /* check NaN */
43 f = MPFR_DBL_NAN;
44 mpfr_set_float128 (x, f, MPFR_RNDN);
45 if (! mpfr_nan_p (x))
46 {
47 printf ("Error in mpfr_set_float128(x, NaN)\n");
48 printf ("got ");
49 mpfr_dump (x);
50 exit (1);
51 }
52 f = mpfr_get_float128 (x, MPFR_RNDN);
53 if (! DOUBLE_ISNAN (f))
54 {
55 printf ("Error in mpfr_get_float128(NaN)\n");
56 printf ("got %f\n", (double) f);
57 exit (1);
58 }
59
60 /* check +Inf */
61 f = MPFR_DBL_INFP;
62 mpfr_set_float128 (x, f, MPFR_RNDN);
63 if (! mpfr_inf_p (x) || MPFR_IS_NEG (x))
64 {
65 printf ("Error in mpfr_set_float128(x, +Inf)\n");
66 printf ("got ");
67 mpfr_dump (x);
68 exit (1);
69 }
70 f = mpfr_get_float128 (x, MPFR_RNDN);
71 if (f != MPFR_DBL_INFP)
72 {
73 printf ("Error in mpfr_get_float128(+Inf)\n");
74 printf ("got %f\n", (double) f);
75 exit (1);
76 }
77
78 /* check -Inf */
79 f = MPFR_DBL_INFM;
80 mpfr_set_float128 (x, f, MPFR_RNDN);
81 if (! mpfr_inf_p (x) || MPFR_IS_POS (x))
82 {
83 printf ("Error in mpfr_set_float128(x, -Inf)\n");
84 printf ("got ");
85 mpfr_dump (x);
86 exit (1);
87 }
88 f = mpfr_get_float128 (x, MPFR_RNDN);
89 if (f != MPFR_DBL_INFM)
90 {
91 printf ("Error in mpfr_get_float128(-Inf)\n");
92 printf ("got %f\n", (double) f);
93 exit (1);
94 }
95 #endif
96
97 /* check +0 */
98 f = 0.0;
99 mpfr_set_float128 (x, f, MPFR_RNDN);
100 if (! mpfr_zero_p (x) || MPFR_IS_NEG (x))
101 {
102 printf ("Error in mpfr_set_float128(x, +0)\n");
103 printf ("got ");
104 mpfr_dump (x);
105 exit (1);
106 }
107 f = mpfr_get_float128 (x, MPFR_RNDN);
108 if (f != 0.0) /* the sign is not checked */
109 {
110 printf ("Error in mpfr_get_float128(+0.0)\n");
111 printf ("got %f\n", (double) f);
112 exit (1);
113 }
114 #if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ)
115 if (1 / f != MPFR_DBL_INFP) /* check the sign */
116 {
117 printf ("Error in mpfr_get_float128(+0.0)\n");
118 printf ("got %f\n", (double) f);
119 exit (1);
120 }
121 #endif
122
123 /* check -0 */
124 f = -0.0;
125 mpfr_set_float128 (x, f, MPFR_RNDN);
126 if (! mpfr_zero_p (x))
127 {
128 printf ("Error in mpfr_set_float128(x, -0)\n");
129 printf ("got ");
130 mpfr_dump (x);
131 exit (1);
132 }
133 #if defined(HAVE_SIGNEDZ)
134 if (MPFR_IS_POS (x))
135 {
136 printf ("Error in mpfr_set_float128(x, -0)\n");
137 printf ("got ");
138 mpfr_dump (x);
139 exit (1);
140 }
141 #endif
142 f = mpfr_get_float128 (x, MPFR_RNDN);
143 if (f != -0.0) /* the sign is not checked */
144 {
145 printf ("Error in mpfr_get_float128(-0.0)\n");
146 printf ("got %f\n", (double) f);
147 exit (1);
148 }
149 #if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ)
150 if (1 / f != MPFR_DBL_INFM) /* check the sign */
151 {
152 printf ("Error in mpfr_get_float128(-0.0)\n");
153 printf ("got %f\n", (double) f);
154 exit (1);
155 }
156 #endif
157
158 mpfr_clear (x);
159 }
160
161 static void
check_large(void)162 check_large (void)
163 {
164 mpfr_exp_t emin, emax;
165 _Float128 f, e;
166 int i;
167 mpfr_t x, y;
168 int r;
169 int red;
170
171 emin = mpfr_get_emin ();
172 emax = mpfr_get_emax ();
173
174 mpfr_init2 (x, 113);
175 mpfr_init2 (y, 113);
176
177 /* check with the largest float128 number 2^16384*(1-2^(-113)) */
178 for (f = 1.0, i = 0; i < 113; i++)
179 f = f + f;
180 f = f - (_Float128) 1.0;
181 mpfr_set_ui (y, 1, MPFR_RNDN);
182 mpfr_mul_2ui (y, y, 113, MPFR_RNDN);
183 mpfr_sub_ui (y, y, 1, MPFR_RNDN);
184 for (i = 113; i < 16384; i++)
185 {
186 RND_LOOP (r)
187 {
188 mpfr_set_float128 (x, f, (mpfr_rnd_t) r);
189 if (! mpfr_equal_p (x, y))
190 {
191 printf ("mpfr_set_float128 failed for 2^%d*(1-2^(-113)) rnd=%s\n",
192 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
193 printf ("got ");
194 mpfr_dump (x);
195 exit (1);
196 }
197 for (red = 0; red < 2; red++)
198 {
199 if (red)
200 {
201 mpfr_exp_t ex;
202
203 if (MPFR_IS_SINGULAR (x))
204 break;
205 ex = MPFR_GET_EXP (x);
206 set_emin (ex);
207 set_emax (ex);
208 }
209 e = mpfr_get_float128 (x, (mpfr_rnd_t) r);
210 set_emin (emin);
211 set_emax (emax);
212 if (e != f)
213 {
214 printf ("mpfr_get_float128 failed for 2^%d*(1-2^(-113))"
215 " rnd=%s%s\n",
216 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r),
217 red ? ", reduced exponent range" : "");
218 exit (1);
219 }
220 }
221 }
222
223 /* check with opposite number */
224 f = -f;
225 mpfr_neg (y, y, MPFR_RNDN);
226 RND_LOOP (r)
227 {
228 mpfr_set_float128 (x, f, (mpfr_rnd_t) r);
229 if (! mpfr_equal_p (x, y))
230 {
231 printf ("mpfr_set_float128 failed for -2^%d*(1-2^(-113)) rnd=%s\n",
232 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
233 printf ("got ");
234 mpfr_dump (x);
235 exit (1);
236 }
237 e = mpfr_get_float128 (x, (mpfr_rnd_t) r);
238 if (e != f)
239 {
240 printf ("mpfr_get_float128 failed for -2^%d*(1-2^(-113)) rnd=%s\n",
241 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
242 exit (1);
243 }
244 }
245
246 f = -f;
247 mpfr_neg (y, y, MPFR_RNDN);
248 f = f + f;
249 mpfr_add (y, y, y, MPFR_RNDN);
250 }
251
252 mpfr_clear (x);
253 mpfr_clear (y);
254 }
255
256 static void
check_small(void)257 check_small (void)
258 {
259 int t[5] = { 1, 2, 17, 111, 112 };
260 mpfr_exp_t emin;
261 _Float128 e, f;
262 int i, j, neg, inex, r;
263 mpfr_t w, x, y, z;
264
265 emin = mpfr_get_emin ();
266
267 mpfr_inits2 (113, w, x, y, z, (mpfr_ptr) 0);
268
269 f = 1.0;
270 mpfr_set_ui (y, 1, MPFR_RNDN);
271 for (i = 0; i > -16500; i--)
272 {
273 for (j = 0; j < 5; j++)
274 {
275 mpfr_div_2ui (z, y, t[j], MPFR_RNDN);
276 inex = mpfr_add (z, z, y, MPFR_RNDN);
277 MPFR_ASSERTN (inex == 0);
278 /* z = y (1 + 2^(-t[j]) */
279 for (neg = 0; neg < 2; neg++)
280 {
281 RND_LOOP_NO_RNDF (r)
282 {
283 if (j == 0 && f != 0)
284 {
285 /* This test does not depend on j. */
286 mpfr_set_float128 (x, f, (mpfr_rnd_t) r);
287 if (! mpfr_equal_p (x, y))
288 {
289 printf ("mpfr_set_float128 failed for "
290 "%c2^(%d) rnd=%s\n", neg ? '-' : '+', i,
291 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
292 printf ("got ");
293 mpfr_dump (x);
294 exit (1);
295 }
296 e = mpfr_get_float128 (x, (mpfr_rnd_t) r);
297 if (e != f)
298 {
299 printf ("mpfr_get_float128 failed for "
300 "%c2^(%d) rnd=%s\n", neg ? '-' : '+', i,
301 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
302 exit (1);
303 }
304 }
305 if (i < -16378)
306 {
307 /* Subnormals or close to subnormals...
308 Here we mainly test mpfr_get_float128. */
309 e = mpfr_get_float128 (z, (mpfr_rnd_t) r);
310 mpfr_set_float128 (x, e, MPFR_RNDN); /* exact */
311 inex = mpfr_set (w, z, MPFR_RNDN);
312 MPFR_ASSERTN (inex == 0);
313 set_emin (-16493);
314 inex = mpfr_check_range (w, 0, (mpfr_rnd_t) r);
315 mpfr_subnormalize (w, inex, (mpfr_rnd_t) r);
316 set_emin (emin);
317 if (! mpfr_equal_p (x, w))
318 {
319 printf ("mpfr_get_float128 failed for "
320 "%c(2^(%d))(1+2^(-%d)) rnd=%s\n",
321 neg ? '-' : '+', i, t[j],
322 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
323 printf ("expected ");
324 mpfr_dump (w);
325 printf ("got ");
326 mpfr_dump (x);
327 exit (1);
328 }
329 }
330 }
331 f = -f;
332 mpfr_neg (y, y, MPFR_RNDN);
333 mpfr_neg (z, z, MPFR_RNDN);
334 }
335 }
336 f = 0.5 * f;
337 mpfr_div_2ui (y, y, 1, MPFR_RNDN);
338 }
339
340 mpfr_clears (w, x, y, z, (mpfr_ptr) 0);
341 }
342
343 int
main(int argc,char * argv[])344 main (int argc, char *argv[])
345 {
346 tests_start_mpfr ();
347
348 check_special ();
349
350 check_large ();
351
352 check_small ();
353
354 tests_end_mpfr ();
355
356 return 0;
357 }
358
359 #else /* MPFR_WANT_FLOAT128 */
360
361 /* dummy main to say this test is ignored */
362 int
main(void)363 main (void)
364 {
365 return 77;
366 }
367
368 #endif /* MPFR_WANT_FLOAT128 */
369