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