xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_float128.c (revision ec6772edaf0cdcb5f52a48f4aca5e33a8fb8ecfd)
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