xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_float128.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
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
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       exit (1);
49     }
50   f = mpfr_get_float128 (x, MPFR_RNDN);
51   if (! DOUBLE_ISNAN (f))
52     {
53       printf ("Error in mpfr_get_float128(NaN)\n");
54       printf ("got %f\n", (double) f);
55       exit (1);
56     }
57 
58   /* check +Inf */
59   f = MPFR_DBL_INFP;
60   mpfr_set_float128 (x, f, MPFR_RNDN);
61   if (! mpfr_inf_p (x) || MPFR_IS_NEG (x))
62     {
63       printf ("Error in mpfr_set_float128(x, +Inf)\n");
64       exit (1);
65     }
66   f = mpfr_get_float128 (x, MPFR_RNDN);
67   if (f != MPFR_DBL_INFP)
68     {
69       printf ("Error in mpfr_get_float128(+Inf)\n");
70       exit (1);
71     }
72 
73   /* check -Inf */
74   f = MPFR_DBL_INFM;
75   mpfr_set_float128 (x, f, MPFR_RNDN);
76   if (! mpfr_inf_p (x) || MPFR_IS_POS (x))
77     {
78       printf ("Error in mpfr_set_float128(x, -Inf)\n");
79       exit (1);
80     }
81   f = mpfr_get_float128 (x, MPFR_RNDN);
82   if (f != MPFR_DBL_INFM)
83     {
84       printf ("Error in mpfr_get_float128(-Inf)\n");
85       exit (1);
86     }
87 #endif
88 
89   /* check +0 */
90   f = 0.0;
91   mpfr_set_float128 (x, f, MPFR_RNDN);
92   if (! mpfr_zero_p (x) || MPFR_IS_NEG (x))
93     {
94       printf ("Error in mpfr_set_float128(x, +0)\n");
95       exit (1);
96     }
97   f = mpfr_get_float128 (x, MPFR_RNDN);
98   if (f != 0.0)  /* the sign is not checked */
99     {
100       printf ("Error in mpfr_get_float128(+0.0)\n");
101       exit (1);
102     }
103 #if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ)
104   if (1 / f != MPFR_DBL_INFP)  /* check the sign */
105     {
106       printf ("Error in mpfr_get_float128(+0.0)\n");
107       exit (1);
108     }
109 #endif
110 
111   /* check -0 */
112   f = -0.0;
113   mpfr_set_float128 (x, f, MPFR_RNDN);
114   if (! mpfr_zero_p (x))
115     {
116       printf ("Error in mpfr_set_float128(x, -0)\n");
117       exit (1);
118     }
119 #if defined(HAVE_SIGNEDZ)
120   if (MPFR_IS_POS (x))
121     {
122       printf ("Error in mpfr_set_float128(x, -0)\n");
123       exit (1);
124     }
125 #endif
126   f = mpfr_get_float128 (x, MPFR_RNDN);
127   if (f != -0.0)  /* the sign is not checked */
128     {
129       printf ("Error in mpfr_get_float128(-0.0)\n");
130       exit (1);
131     }
132 #if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ)
133   if (1 / f != MPFR_DBL_INFM)  /* check the sign */
134     {
135       printf ("Error in mpfr_get_float128(-0.0)\n");
136       exit (1);
137     }
138 #endif
139 
140   mpfr_clear (x);
141 }
142 
143 static void
144 check_large (void)
145 {
146   mpfr_exp_t emin, emax;
147   _Float128 f, e;
148   int i;
149   mpfr_t x, y;
150   int r;
151   int red;
152 
153   emin = mpfr_get_emin ();
154   emax = mpfr_get_emax ();
155 
156   mpfr_init2 (x, 113);
157   mpfr_init2 (y, 113);
158 
159   /* check with the largest float128 number 2^16384*(1-2^(-113)) */
160   for (f = 1.0, i = 0; i < 113; i++)
161     f = f + f;
162   f = f - (_Float128) 1.0;
163   mpfr_set_ui (y, 1, MPFR_RNDN);
164   mpfr_mul_2ui (y, y, 113, MPFR_RNDN);
165   mpfr_sub_ui (y, y, 1, MPFR_RNDN);
166   for (i = 113; i < 16384; i++)
167     {
168       RND_LOOP (r)
169         {
170           mpfr_set_float128 (x, f, (mpfr_rnd_t) r);
171           if (! mpfr_equal_p (x, y))
172             {
173               printf ("mpfr_set_float128 failed for 2^%d*(1-2^(-113)) rnd=%s\n",
174                       i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
175               printf ("got ");
176               mpfr_dump (x);
177               exit (1);
178             }
179           for (red = 0; red < 2; red++)
180             {
181               if (red)
182                 {
183                   mpfr_exp_t ex;
184 
185                   if (MPFR_IS_SINGULAR (x))
186                     break;
187                   ex = MPFR_GET_EXP (x);
188                   set_emin (ex);
189                   set_emax (ex);
190                 }
191               e =  mpfr_get_float128 (x, (mpfr_rnd_t) r);
192               set_emin (emin);
193               set_emax (emax);
194               if (e != f)
195                 {
196                   printf ("mpfr_get_float128 failed for 2^%d*(1-2^(-113))"
197                           " rnd=%s%s\n",
198                           i, mpfr_print_rnd_mode ((mpfr_rnd_t) r),
199                           red ? ", reduced exponent range" : "");
200                   exit (1);
201                 }
202             }
203         }
204 
205       /* check with opposite number */
206       f = -f;
207       mpfr_neg (y, y, MPFR_RNDN);
208       RND_LOOP (r)
209         {
210           mpfr_set_float128 (x, f, (mpfr_rnd_t) r);
211           if (! mpfr_equal_p (x, y))
212             {
213               printf ("mpfr_set_float128 failed for -2^%d*(1-2^(-113)) rnd=%s\n",
214                       i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
215               printf ("got ");
216               mpfr_dump (x);
217               exit (1);
218             }
219           e =  mpfr_get_float128 (x, (mpfr_rnd_t) r);
220           if (e != f)
221             {
222               printf ("mpfr_get_float128 failed for -2^%d*(1-2^(-113)) rnd=%s\n",
223                       i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
224               exit (1);
225             }
226         }
227 
228       f = -f;
229       mpfr_neg (y, y, MPFR_RNDN);
230       f = f + f;
231       mpfr_add (y, y, y, MPFR_RNDN);
232     }
233 
234   mpfr_clear (x);
235   mpfr_clear (y);
236 }
237 
238 static void
239 check_small (void)
240 {
241   int t[5] = { 1, 2, 17, 111, 112 };
242   mpfr_exp_t emin;
243   _Float128 e, f;
244   int i, j, neg, inex, r;
245   mpfr_t w, x, y, z;
246 
247   emin = mpfr_get_emin ();
248 
249   mpfr_inits2 (113, w, x, y, z, (mpfr_ptr) 0);
250 
251   f = 1.0;
252   mpfr_set_ui (y, 1, MPFR_RNDN);
253   for (i = 0; i > -16500; i--)
254     {
255       for (j = 0; j < 5; j++)
256         {
257           mpfr_div_2ui (z, y, t[j], MPFR_RNDN);
258           inex = mpfr_add (z, z, y, MPFR_RNDN);
259           MPFR_ASSERTN (inex == 0);
260           /* z = y (1 + 2^(-t[j]) */
261           for (neg = 0; neg < 2; neg++)
262             {
263               RND_LOOP_NO_RNDF (r)
264                 {
265                   if (j == 0 && f != 0)
266                     {
267                       /* This test does not depend on j. */
268                       mpfr_set_float128 (x, f, (mpfr_rnd_t) r);
269                       if (! mpfr_equal_p (x, y))
270                         {
271                           printf ("mpfr_set_float128 failed for "
272                                   "%c2^(%d) rnd=%s\n", neg ? '-' : '+', i,
273                                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
274                           printf ("got ");
275                           mpfr_dump (x);
276                           exit (1);
277                         }
278                       e =  mpfr_get_float128 (x, (mpfr_rnd_t) r);
279                       if (e != f)
280                         {
281                           printf ("mpfr_get_float128 failed for "
282                                   "%c2^(%d) rnd=%s\n", neg ? '-' : '+', i,
283                                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
284                           exit (1);
285                         }
286                     }
287                   if (i < -16378)
288                     {
289                       /* Subnormals or close to subnormals...
290                          Here we mainly test mpfr_get_float128. */
291                       e =  mpfr_get_float128 (z, (mpfr_rnd_t) r);
292                       mpfr_set_float128 (x, e, MPFR_RNDN); /* exact */
293                       inex = mpfr_set (w, z, MPFR_RNDN);
294                       MPFR_ASSERTN (inex == 0);
295                       set_emin (-16493);
296                       inex = mpfr_check_range (w, 0, (mpfr_rnd_t) r);
297                       mpfr_subnormalize (w, inex, (mpfr_rnd_t) r);
298                       set_emin (emin);
299                       if (! mpfr_equal_p (x, w))
300                         {
301                           printf ("mpfr_get_float128 failed for "
302                                   "%c(2^(%d))(1+2^(-%d)) rnd=%s\n",
303                                   neg ? '-' : '+', i, t[j],
304                                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
305                           printf ("expected ");
306                           mpfr_dump (w);
307                           printf ("got      ");
308                           mpfr_dump (x);
309                           exit (1);
310                         }
311                     }
312                 }
313               f = -f;
314               mpfr_neg  (y, y, MPFR_RNDN);
315               mpfr_neg  (z, z, MPFR_RNDN);
316             }
317         }
318       f =  0.5 * f;
319       mpfr_div_2ui (y, y, 1, MPFR_RNDN);
320     }
321 
322   mpfr_clears (w, x, y, z, (mpfr_ptr) 0);
323 }
324 
325 int
326 main (int argc, char *argv[])
327 {
328   tests_start_mpfr ();
329 
330   check_special ();
331 
332   check_large ();
333 
334   check_small ();
335 
336   tests_end_mpfr ();
337 
338   return 0;
339 }
340 
341 #else /* MPFR_WANT_FLOAT128 */
342 
343 /* dummy main to say this test is ignored */
344 int
345 main (void)
346 {
347   return 77;
348 }
349 
350 #endif /* MPFR_WANT_FLOAT128 */
351