xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tget_flt.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_get_flt and mpfr_set_flt
2 
3 Copyright 2009-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 #include <float.h>     /* for FLT_MIN */
24 
25 #include "mpfr-test.h"
26 #include "ieee_floats.h"
27 
28 /* return non-zero iff f == g, and if both are zero check the sign */
29 static int
equal_flt(float f,float g)30 equal_flt (float f, float g)
31 {
32   if (f != 0.0)
33     return f == g;
34   else if (g != 0)
35     return 0;
36   else /* f = g = 0: check they have the same sign */
37     {
38       int sf, sg;
39       mpfr_t z;
40 
41       mpfr_init2 (z, MPFR_PREC_MIN);
42       mpfr_set_flt (z, f, MPFR_RNDN);
43       sf = mpfr_signbit (z);
44       mpfr_set_flt (z, g, MPFR_RNDN);
45       sg = mpfr_signbit (z);
46       mpfr_clear (z);
47       return !sf == !sg;
48     }
49 }
50 
51 int
main(void)52 main (void)
53 {
54   mpfr_t x, y;
55   float f, g;
56   int i;
57 #if !defined(MPFR_ERRDIVZERO)
58   float infp;
59 #endif
60 
61   tests_start_mpfr ();
62 
63 #if !defined(MPFR_ERRDIVZERO)
64   infp = (float) MPFR_DBL_INFP;
65   if (infp * 0.5 != infp)
66     {
67       fprintf (stderr, "Error, FLT_MAX + FLT_MAX does not yield INFP\n");
68       fprintf (stderr, "(this is probably a compiler bug, please report)\n");
69       exit (1);
70     }
71 #endif
72 
73   mpfr_init2 (x, 24);
74   mpfr_init2 (y, 24);
75 
76 #if !defined(MPFR_ERRDIVZERO)
77   mpfr_set_nan (x);
78   f = mpfr_get_flt (x, MPFR_RNDN);
79   if (! DOUBLE_ISNAN (f))
80     {
81       printf ("Error for mpfr_get_flt(NaN)\n");
82       printf ("got f=%f\n", f);
83       exit (1);
84     }
85   mpfr_set_flt (x, f, MPFR_RNDN);
86   if (! mpfr_nan_p (x))
87     {
88       printf ("Error for mpfr_set_flt(NaN)\n");
89       exit (1);
90     }
91 
92   mpfr_set_inf (x, 1);
93   f = mpfr_get_flt (x, MPFR_RNDN);
94   mpfr_set_flt (x, f, MPFR_RNDN);
95   if (! mpfr_inf_p (x) || mpfr_sgn (x) < 0)
96     {
97       printf ("Error for mpfr_set_flt(mpfr_get_flt(+Inf)):\n");
98       printf ("f=%f, expected -Inf\n", f);
99       printf ("got "); mpfr_dump (x);
100       exit (1);
101     }
102 
103   mpfr_set_inf (x, -1);
104   f = mpfr_get_flt (x, MPFR_RNDN);
105   mpfr_set_flt (x, f, MPFR_RNDN);
106   if (! mpfr_inf_p (x) || mpfr_sgn (x) > 0)
107     {
108       printf ("Error for mpfr_set_flt(mpfr_get_flt(-Inf)):\n");
109       printf ("f=%f, expected -Inf\n", f);
110       printf ("got "); mpfr_dump (x);
111       exit (1);
112     }
113 #endif
114 
115   mpfr_set_ui (x, 0, MPFR_RNDN);
116   f = mpfr_get_flt (x, MPFR_RNDN);
117   mpfr_set_flt (x, f, MPFR_RNDN);
118   if (! mpfr_zero_p (x) || MPFR_IS_NEG (x))
119     {
120       printf ("Error for mpfr_set_flt(mpfr_get_flt(+0))\n");
121       exit (1);
122     }
123 
124 #ifdef HAVE_SIGNEDZ
125   mpfr_set_ui (x, 0, MPFR_RNDN);
126   mpfr_neg (x, x, MPFR_RNDN);
127   f = mpfr_get_flt (x, MPFR_RNDN);
128   mpfr_set_flt (x, f, MPFR_RNDN);
129   if (! mpfr_zero_p (x) || MPFR_IS_POS (x))
130     {
131       printf ("Error for mpfr_set_flt(mpfr_get_flt(-0))\n");
132       exit (1);
133     }
134 #endif  /* HAVE_SIGNEDZ */
135 
136   mpfr_set_ui (x, 17, MPFR_RNDN);
137   f = mpfr_get_flt (x, MPFR_RNDN);
138   mpfr_set_flt (x, f, MPFR_RNDN);
139   if (mpfr_cmp_ui (x, 17) != 0)
140     {
141       printf ("Error for mpfr_set_flt(mpfr_get_flt(17))\n");
142       printf ("expected 17\n");
143       printf ("got      ");
144       mpfr_dump (x);
145       exit (1);
146     }
147 
148   mpfr_set_si (x, -42, MPFR_RNDN);
149   f = mpfr_get_flt (x, MPFR_RNDN);
150   mpfr_set_flt (x, f, MPFR_RNDN);
151   if (mpfr_cmp_si (x, -42) != 0)
152     {
153       printf ("Error for mpfr_set_flt(mpfr_get_flt(-42))\n");
154       printf ("expected -42\n");
155       printf ("got      ");
156       mpfr_dump (x);
157       exit (1);
158     }
159 
160   mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
161   for (i = -126; i < 128; i++)
162     {
163       f = mpfr_get_flt (x, MPFR_RNDN);
164       mpfr_set_flt (y, f, MPFR_RNDN);
165       if (mpfr_cmp (x, y) != 0)
166         {
167           printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
168           printf ("expected "); mpfr_dump (x);
169           printf ("got      "); mpfr_dump (y);
170           exit (1);
171         }
172       mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
173     }
174 
175   mpfr_set_prec (x, 53);
176   mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
177   for (i = -126; i < 128; i++)
178     {
179       mpfr_nextbelow (x);
180       f = mpfr_get_flt (x, MPFR_RNDN);
181       mpfr_nextabove (x);
182       mpfr_set_flt (y, f, MPFR_RNDN);
183       if (mpfr_cmp (x, y) != 0)
184         {
185           printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
186           printf ("expected "); mpfr_dump (x);
187           printf ("got      "); mpfr_dump (y);
188           exit (1);
189         }
190       mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
191     }
192 
193   mpfr_set_prec (x, 53);
194   mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
195   for (i = -126; i < 128; i++)
196     {
197       mpfr_nextabove (x);
198       f = mpfr_get_flt (x, MPFR_RNDN);
199       mpfr_nextbelow (x);
200       mpfr_set_flt (y, f, MPFR_RNDN);
201       if (mpfr_cmp (x, y) != 0)
202         {
203           printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
204           printf ("expected "); mpfr_dump (x);
205           printf ("got      "); mpfr_dump (y);
206           exit (1);
207         }
208       mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
209     }
210 
211   if (have_subnorm_flt ())
212     for (i = 0; i < 2; i++)
213       {
214         /* We assume here that the format of float is binary32, a.k.a.
215            IEEE single precision (Annex F of ISO C for IEEE 754 support),
216            as this is the case on all machines nowadays. Then 2^(-150) is
217            halfway between 0 and the smallest positive float 2^(-149). */
218         mpfr_set_si_2exp (x, 1, -150, MPFR_RNDN);
219         g = 0.0;
220         if (i == 1)
221           {
222             mpfr_neg (x, x, MPFR_RNDN);
223             g = -g;
224           }
225         f = mpfr_get_flt (x, MPFR_RNDN);
226         if (!equal_flt (f, g))
227           {
228             printf ("Error for mpfr_get_flt(2^(-150),RNDN)\n");
229             printf ("expected %.8e, got %.8e\n", g, f);
230             exit (1);
231           }
232         f = mpfr_get_flt (x, MPFR_RNDZ);
233         if (!equal_flt (f, g))
234           {
235             printf ("Error for mpfr_get_flt(2^(-150),RNDZ)\n");
236             printf ("expected %.8e, got %.8e\n", g, f);
237             exit (1);
238           }
239         f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDD : MPFR_RNDU);
240         if (!equal_flt (f, g))
241           {
242             printf ("Error for mpfr_get_flt(2^(-150),%s)\n",
243                     i == 0 ? "RNDD" : "RNDU");
244             printf ("expected %.8e, got %.8e\n", g, f);
245             exit (1);
246           }
247         g = FLT_MIN * FLT_EPSILON;
248         if (i == 1)
249           g = -g;
250         f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDU : MPFR_RNDD);
251         if (!equal_flt (f, g))
252           {
253             printf ("Error for mpfr_get_flt(2^(-150),%s)\n",
254                     i == 0 ? "RNDU" : "RNDD");
255             printf ("expected %.8e, got %.8e\n", g, f);
256             exit (1);
257           }
258         f = mpfr_get_flt (x, MPFR_RNDA);
259         if (!equal_flt (f, g))
260           {
261             printf ("Error for mpfr_get_flt(2^(-150),RNDA)\n");
262             printf ("expected %.8e, got %.8e\n", g, f);
263             exit (1);
264           }
265 
266         mpfr_set_si_2exp (x, 1, -151, MPFR_RNDN);
267         g = 0.0;
268         if (i == 1)
269           {
270             mpfr_neg (x, x, MPFR_RNDN);
271             g = -g;
272           }
273         f = mpfr_get_flt (x, MPFR_RNDN);
274         if (!equal_flt (f, g))
275           {
276             printf ("Error for mpfr_get_flt(2^(-151),RNDN)\n");
277             printf ("expected %.8e, got %.8e\n", g, f);
278             exit (1);
279           }
280         f = mpfr_get_flt (x, MPFR_RNDZ);
281         if (!equal_flt (f, g))
282           {
283             printf ("Error for mpfr_get_flt(2^(-151),RNDZ)\n");
284             printf ("expected %.8e, got %.8e\n", g, f);
285             exit (1);
286           }
287         f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDD : MPFR_RNDU);
288         if (!equal_flt (f, g))
289           {
290             printf ("Error for mpfr_get_flt(2^(-151),%s)\n",
291                     i == 0 ? "RNDD" : "RNDU");
292             printf ("expected %.8e, got %.8e\n", g, f);
293             exit (1);
294           }
295         g = FLT_MIN * FLT_EPSILON;
296         if (i == 1)
297           g = -g;
298         f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDU : MPFR_RNDD);
299         if (!equal_flt (f, g))
300           {
301             printf ("Error for mpfr_get_flt(2^(-151),%s)\n",
302                     i == 0 ? "RNDU" : "RNDD");
303             printf ("expected %.8e, got %.8e\n", g, f);
304             exit (1);
305           }
306         f = mpfr_get_flt (x, MPFR_RNDA);
307         if (!equal_flt (f, g))
308           {
309             printf ("Error for mpfr_get_flt(2^(-151),RNDA)\n");
310             printf ("expected %.8e, got %.8e\n", g, f);
311             exit (1);
312           }
313 
314         mpfr_set_si_2exp (x, 1, -149, MPFR_RNDN);
315         g = FLT_MIN * FLT_EPSILON;
316         if (i == 1)
317           {
318             mpfr_neg (x, x, MPFR_RNDN);
319             g = -g;
320           }
321         f = mpfr_get_flt (x, MPFR_RNDN);
322         if (!equal_flt (f, g))
323           {
324             printf ("Error for mpfr_get_flt(2^(-149),RNDN)\n");
325             printf ("expected %.8e, got %.8e\n", g, f);
326             exit (1);
327           }
328         f = mpfr_get_flt (x, MPFR_RNDZ);
329         if (!equal_flt (f, g))
330           {
331             printf ("Error for mpfr_get_flt(2^(-149),RNDZ)\n");
332             printf ("expected %.8e, got %.8e\n", g, f);
333             exit (1);
334           }
335         f = mpfr_get_flt (x, MPFR_RNDD);
336         if (!equal_flt (f, g))
337           {
338             printf ("Error for mpfr_get_flt(2^(-149),RNDD)\n");
339             printf ("expected %.8e, got %.8e\n", g, f);
340             exit (1);
341           }
342         f = mpfr_get_flt (x, MPFR_RNDU);
343         if (!equal_flt (f, g))
344           {
345             printf ("Error for mpfr_get_flt(2^(-149),RNDU)\n");
346             printf ("expected %.8e, got %.8e\n", g, f);
347             exit (1);
348           }
349         f = mpfr_get_flt (x, MPFR_RNDA);
350         if (!equal_flt (f, g))
351           {
352             printf ("Error for mpfr_get_flt(2^(-149),RNDA)\n");
353             printf ("expected %.8e, got %.8e\n", g, f);
354             exit (1);
355           }
356       }  /* for loop with tests on subnormals */
357 
358   mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
359   g = FLT_MAX;
360   f = mpfr_get_flt (x, MPFR_RNDZ);
361   if (f != g)
362     {
363       printf ("Error for mpfr_get_flt(2^128,RNDZ)\n");
364       printf ("expected %.8e, got %.8e\n", g, f);
365       exit (1);
366     }
367   f = mpfr_get_flt (x, MPFR_RNDD);
368   if (f != g)
369     {
370       printf ("Error for mpfr_get_flt(2^128,RNDD)\n");
371       printf ("expected %.8e, got %.8e\n", g, f);
372       exit (1);
373     }
374 
375   /* same for negative x */
376   mpfr_set_si_2exp (x, -1, 128, MPFR_RNDN);
377   g = -FLT_MAX;
378   f = mpfr_get_flt (x, MPFR_RNDZ);
379   if (f != g)
380     {
381       printf ("Error for mpfr_get_flt(-2^128,RNDZ)\n");
382       printf ("expected %.8e, got %.8e\n", g, f);
383       exit (1);
384     }
385   f = mpfr_get_flt (x, MPFR_RNDU);
386   if (f != g)
387     {
388       printf ("Error for mpfr_get_flt(-2^128,RNDD)\n");
389       printf ("expected %.8e, got %.8e\n", g, f);
390       exit (1);
391     }
392 
393 #if !defined(MPFR_ERRDIVZERO)
394   mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
395   f = mpfr_get_flt (x, MPFR_RNDN); /* 2^128 rounds to itself with extended
396                                       exponent range, we should get +Inf */
397   g = infp;
398   if (f != g)
399     {
400       printf ("Error for mpfr_get_flt(2^128,RNDN)\n");
401       printf ("expected %.8e, got %.8e\n", g, f);
402       exit (1);
403     }
404   f = mpfr_get_flt (x, MPFR_RNDU);
405   if (f != g)
406     {
407       printf ("Error for mpfr_get_flt(2^128,RNDU)\n");
408       printf ("expected %.8e, got %.8e\n", g, f);
409       exit (1);
410     }
411   f = mpfr_get_flt (x, MPFR_RNDA);
412   if (f != g)
413     {
414       printf ("Error for mpfr_get_flt(2^128,RNDA)\n");
415       printf ("expected %.8e, got %.8e\n", g, f);
416       exit (1);
417     }
418 
419   /* same for negative x */
420   mpfr_set_si_2exp (x, -1, 128, MPFR_RNDN);
421   f = mpfr_get_flt (x, MPFR_RNDN); /* -2^128 rounds to itself with extended
422                                       exponent range, we should get +Inf */
423   g = -infp;
424   if (f != g)
425     {
426       printf ("Error for mpfr_get_flt(-2^128,RNDN)\n");
427       printf ("expected %.8e, got %.8e\n", g, f);
428       exit (1);
429     }
430   f = mpfr_get_flt (x, MPFR_RNDD);
431   if (f != g)
432     {
433       printf ("Error for mpfr_get_flt(-2^128,RNDD)\n");
434       printf ("expected %.8e, got %.8e\n", g, f);
435       exit (1);
436     }
437   f = mpfr_get_flt (x, MPFR_RNDA);
438   if (f != g)
439     {
440       printf ("Error for mpfr_get_flt(-2^128,RNDA)\n");
441       printf ("expected %.8e, got %.8e\n", g, f);
442       exit (1);
443     }
444 #endif
445 
446   /* corner case: take x with 25 bits just below 2^128 */
447   mpfr_set_prec (x, 25);
448   mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
449   mpfr_nextbelow (x);
450   g = FLT_MAX;
451   f = mpfr_get_flt (x, MPFR_RNDZ);
452   if (f != g)
453     {
454       printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDZ)\n");
455       printf ("expected %.8e, got %.8e\n", g, f);
456       exit (1);
457     }
458   f = mpfr_get_flt (x, MPFR_RNDD);
459   if (f != g)
460     {
461       printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDD)\n");
462       printf ("expected %.8e, got %.8e\n", g, f);
463       exit (1);
464     }
465 #if !defined(MPFR_ERRDIVZERO)
466   f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule),
467                                       thus we should get +Inf */
468   g = infp;
469   if (f != g)
470     {
471       printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDN)\n");
472       printf ("expected %.8e, got %.8e\n", g, f);
473       exit (1);
474     }
475   f = mpfr_get_flt (x, MPFR_RNDU);
476   if (f != g)
477     {
478       printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDU)\n");
479       printf ("expected %.8e, got %.8e\n", g, f);
480       exit (1);
481     }
482   f = mpfr_get_flt (x, MPFR_RNDA);
483   if (f != g)
484     {
485       printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDA)\n");
486       printf ("expected %.8e, got %.8e\n", g, f);
487       exit (1);
488     }
489 #endif
490 
491   mpfr_clear (x);
492   mpfr_clear (y);
493 
494   tests_end_mpfr ();
495   return 0;
496 }
497