1 /* Test file for mpfr_set_ld and mpfr_get_ld.
2
3 Copyright 2002-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>
24
25 #include "mpfr-test.h"
26
27 static void
check_gcc33_bug(void)28 check_gcc33_bug (void)
29 {
30 volatile long double x;
31
32 x = (long double) 9007199254740992.0 + 1.0;
33 if (x != 0.0)
34 return; /* OK */
35 printf
36 ("Detected optimization bug of gcc 3.3 on Alpha concerning long double\n"
37 "comparisons; set_ld tests might fail (set_ld won't work correctly).\n"
38 "See https://gcc.gnu.org/legacy-ml/gcc-bugs/2003-10/msg00853.html for\n"
39 "more information.\n");
40 }
41
42 static int
Isnan_ld(long double d)43 Isnan_ld (long double d)
44 {
45 /* Do not convert d to double as this can give an overflow, which
46 may confuse compilers without IEEE 754 support (such as clang
47 -fsanitize=undefined), or trigger a trap if enabled.
48 The DOUBLE_ISNAN macro should work fine on long double. */
49 if (DOUBLE_ISNAN (d))
50 return 1;
51 LONGDOUBLE_NAN_ACTION (d, goto yes);
52 return 0;
53 yes:
54 return 1;
55 }
56
57 /* Return the minimal number of bits to represent d exactly (0 for zero).
58 If flag is non-zero, also print d. */
59 /* FIXME: This function doesn't work if the rounding precision is reduced. */
60 static mpfr_prec_t
print_binary(long double d,int flag)61 print_binary (long double d, int flag)
62 {
63 long double e, f, r;
64 long exp = 1;
65 mpfr_prec_t prec = 0;
66
67 if (Isnan_ld (d))
68 {
69 if (flag)
70 printf ("NaN\n");
71 return 0;
72 }
73 if (d < (long double) 0.0
74 #if !defined(MPFR_ERRDIVZERO)
75 || (d == (long double) 0.0 && (1.0 / (double) d < 0.0))
76 #endif
77 )
78 {
79 if (flag)
80 printf ("-");
81 d = -d;
82 }
83 /* now d >= 0 */
84 /* Use 2 different tests for Inf, to avoid potential bugs
85 in implementations. */
86 if (Isnan_ld (d - d) || (d > 1 && d * 0.5 == d))
87 {
88 if (flag)
89 printf ("Inf\n");
90 return 0;
91 }
92 if (d == (long double) 0.0)
93 {
94 if (flag)
95 printf ("0.0\n");
96 return prec;
97 }
98 MPFR_ASSERTN (d > 0);
99 e = (long double) 1.0;
100 while (e > d)
101 {
102 e = e * (long double) 0.5;
103 exp --;
104 }
105 if (flag == 2) printf ("1: e=%.36Le\n", e);
106 MPFR_ASSERTN (d >= e);
107 /* FIXME: There can be an overflow here, which may not be supported
108 on all platforms. */
109 while (f = e + e, d >= f)
110 {
111 e = f;
112 exp ++;
113 }
114 if (flag == 2) printf ("2: e=%.36Le\n", e);
115 MPFR_ASSERTN (e <= d && d < f);
116 if (flag == 1)
117 printf ("0.");
118 if (flag == 2) printf ("3: d=%.36Le e=%.36Le prec=%ld\n", d, e,
119 (long) prec);
120 /* Note: the method we use here to extract the bits of d is the following,
121 to deal with the case where the rounding precision is less than the
122 precision of d:
123 (1) we accumulate the upper bits of d into f
124 (2) when accumulating a new bit into f is not exact, we subtract
125 f from d and reset f to 0
126 This is guaranteed to work only when the rounding precision is at least
127 half the precision of d, since otherwise d-f might not be exact.
128 This method does not work with flush-to-zero on underflow. */
129 f = 0.0; /* will hold accumulated powers of 2 */
130 while (1)
131 {
132 prec++;
133 r = f + e;
134 /* r is close to f (in particular in the cases where f+e may
135 not be exact), so that r - f should be exact. */
136 if (r - f != e) /* f+e is not exact */
137 {
138 d -= f; /* should be exact */
139 f = 0.0;
140 r = e;
141 }
142 if (d >= r)
143 {
144 if (flag == 1)
145 printf ("1");
146 if (d == r)
147 break;
148 f = r;
149 }
150 else
151 {
152 if (flag == 1)
153 printf ("0");
154 }
155 e *= (long double) 0.5;
156 MPFR_ASSERTN (e != 0); /* may fail with flush-to-zero on underflow */
157 if (flag == 2) printf ("4: d=%.36Le e=%.36Le prec=%ld\n", d, e,
158 (long) prec);
159 }
160 if (flag == 1)
161 printf ("e%ld\n", exp);
162 return prec;
163 }
164
165 /* Checks that a long double converted exactly to a MPFR number, then
166 converted back to a long double gives the initial value, or in other
167 words, mpfr_get_ld(mpfr_set_ld(d)) = d.
168 */
169 static void
check_set_get(long double d)170 check_set_get (long double d)
171 {
172 mpfr_exp_t emin, emax;
173 mpfr_t x;
174 mpfr_prec_t prec;
175 int r;
176 long double e;
177 int inex;
178 int red;
179
180 emin = mpfr_get_emin ();
181 emax = mpfr_get_emax ();
182
183 /* Select a precision to ensure that the conversion of d to x be exact. */
184 prec = print_binary (d, 0);
185 if (prec < MPFR_PREC_MIN)
186 prec = MPFR_PREC_MIN;
187 mpfr_init2 (x, prec);
188
189 RND_LOOP(r)
190 {
191 inex = mpfr_set_ld (x, d, (mpfr_rnd_t) r);
192 if (inex != 0)
193 {
194 printf ("Error: mpfr_set_ld should be exact (rnd = %s)\n",
195 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
196 /* We use 36 digits here, as the maximum LDBL_MANT_DIG value
197 seen in the current implementations is 113 (binary128),
198 and ceil(1+113*log(2)/log(10)) = 36. But the current glibc
199 implementation of printf with double-double arithmetic
200 (e.g. on PowerPC) is not accurate. */
201 printf (" d ~= %.36Le (output may be wrong!)\n", d);
202 printf (" inex = %d\n", inex);
203 if (emin >= LONG_MIN)
204 printf (" emin = %ld\n", (long) emin);
205 if (emax <= LONG_MAX)
206 printf (" emax = %ld\n", (long) emax);
207 ld_trace (" d", d);
208 printf (" d = ");
209 print_binary (d, 1);
210 printf (" x = ");
211 mpfr_dump (x);
212 printf (" MPFR_LDBL_MANT_DIG=%u\n", MPFR_LDBL_MANT_DIG);
213 printf (" prec=%ld\n", (long) prec);
214 print_binary (d, 2);
215 exit (1);
216 }
217 for (red = 0; red < 2; red++)
218 {
219 if (red)
220 {
221 mpfr_exp_t ex;
222
223 if (MPFR_IS_SINGULAR (x))
224 break;
225 ex = MPFR_GET_EXP (x);
226 set_emin (ex);
227 set_emax (ex);
228 }
229 e = mpfr_get_ld (x, (mpfr_rnd_t) r);
230 set_emin (emin);
231 set_emax (emax);
232 if (inex == 0 && ((Isnan_ld(d) && ! Isnan_ld(e)) ||
233 (Isnan_ld(e) && ! Isnan_ld(d)) ||
234 (e != d && !(Isnan_ld(e) && Isnan_ld(d)))))
235 {
236 printf ("Error: mpfr_get_ld o mpfr_set_ld <> Id%s\n",
237 red ? ", reduced exponent range" : "");
238 printf (" rnd = %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r));
239 printf (" d ~= %.36Le (output may be wrong!)\n", d);
240 printf (" e ~= %.36Le (output may be wrong!)\n", e);
241 ld_trace (" d", d);
242 printf (" x = ");
243 mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
244 printf ("\n");
245 ld_trace (" e", e);
246 printf (" d = ");
247 print_binary (d, 1);
248 printf (" x = ");
249 mpfr_dump (x);
250 printf (" e = ");
251 print_binary (e, 1);
252 printf (" MPFR_LDBL_MANT_DIG=%u\n", MPFR_LDBL_MANT_DIG);
253 #ifdef MPFR_NANISNAN
254 if (Isnan_ld(d) || Isnan_ld(e))
255 printf ("The reason is that NAN == NAN. Please look at the "
256 "configure output\nand Section \"In case of problem\""
257 " of the INSTALL file.\n");
258 #endif
259 exit (1);
260 }
261 }
262 }
263
264 mpfr_clear (x);
265 }
266
267 static void
test_small(void)268 test_small (void)
269 {
270 mpfr_t x, y, z;
271 long double d;
272
273 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
274 mpfr_init2 (y, MPFR_LDBL_MANT_DIG);
275 mpfr_init2 (z, MPFR_LDBL_MANT_DIG);
276
277 /* x = 11906603631607553907/2^(16381+64) */
278 mpfr_set_str (x, "0.1010010100111100110000001110101101000111010110000001111101110011E-16381", 2, MPFR_RNDN);
279 d = mpfr_get_ld (x, MPFR_RNDN); /* infinite loop? */
280 mpfr_set_ld (y, d, MPFR_RNDN);
281 mpfr_sub (z, x, y, MPFR_RNDN);
282 mpfr_abs (z, z, MPFR_RNDN);
283 mpfr_clear_erangeflag ();
284 /* If long double = double, d should be equal to 0;
285 in this case, everything is OK. */
286 if (d != 0 && (mpfr_cmp_str (z, "1E-16434", 2, MPFR_RNDN) > 0 ||
287 mpfr_erangeflag_p ()))
288 {
289 printf ("Error with x = ");
290 mpfr_out_str (stdout, 10, 21, x, MPFR_RNDN);
291 printf (" = ");
292 mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
293 printf ("\n -> d = %.33Le", d);
294 printf ("\n -> y = ");
295 mpfr_out_str (stdout, 10, 21, y, MPFR_RNDN);
296 printf (" = ");
297 mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
298 printf ("\n -> |x-y| = ");
299 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
300 printf ("\n");
301 exit (1);
302 }
303
304 mpfr_clear (x);
305 mpfr_clear (y);
306 mpfr_clear (z);
307 }
308
309 static void
test_fixed_bugs(void)310 test_fixed_bugs (void)
311 {
312 mpfr_t x;
313 long double l, m;
314
315 /* bug found by Steve Kargl (2009-03-14) */
316 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
317 mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN);
318 mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */
319
320 /* bug reported by Jakub Jelinek (2010-10-17)
321 https://gforge.inria.fr/tracker/?func=detail&aid=11300 */
322 mpfr_set_prec (x, MPFR_LDBL_MANT_DIG);
323 /* l = 0x1.23456789abcdef0123456789abcdp-914L; */
324 l = 8.215640181713713164092636634579e-276;
325 mpfr_set_ld (x, l, MPFR_RNDN);
326 m = mpfr_get_ld (x, MPFR_RNDN);
327 if (m != l)
328 {
329 printf ("Error in get_ld o set_ld for l=%Le\n", l);
330 printf ("Got m=%Le instead of l\n", m);
331 exit (1);
332 }
333
334 /* another similar test which failed with extended double precision and the
335 generic code for mpfr_set_ld */
336 /* l = 0x1.23456789abcdef0123456789abcdp-968L; */
337 l = 4.560596445887084662336528403703e-292;
338 mpfr_set_ld (x, l, MPFR_RNDN);
339 m = mpfr_get_ld (x, MPFR_RNDN);
340 if (m != l)
341 {
342 printf ("Error in get_ld o set_ld for l=%Le\n", l);
343 printf ("Got m=%Le instead of l\n", m);
344 exit (1);
345 }
346
347 mpfr_clear (x);
348 }
349
350 static void
check_subnormal(void)351 check_subnormal (void)
352 {
353 long double d, e;
354 mpfr_t x;
355
356 d = 17.0;
357 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
358 while (d != 0.0)
359 {
360 mpfr_set_ld (x, d, MPFR_RNDN);
361 e = mpfr_get_ld (x, MPFR_RNDN);
362 if (e != d)
363 {
364 printf ("Error in check_subnormal for mpfr_get_ld o mpfr_set_ld\n");
365 printf ("d=%.30Le\n", d);
366 printf ("x="); mpfr_dump (x);
367 printf ("e=%.30Le\n", e);
368 exit (1);
369 }
370 d *= 0.5;
371 }
372 mpfr_clear (x);
373 }
374
375 static void
check_overflow(void)376 check_overflow (void)
377 {
378 long double d, e;
379 mpfr_t x;
380 int i;
381
382 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
383 for (i = 0; i < 2; i++)
384 {
385 d = i == 0 ? LDBL_MAX : -LDBL_MAX;
386 mpfr_set_ld (x, d, MPFR_RNDN);
387 mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
388 e = mpfr_get_ld (x, MPFR_RNDN);
389 if (! DOUBLE_ISINF (e) || (i == 0 ? (e < 0) : (e > 0)))
390 {
391 printf ("Error in check_overflow.\n");
392 printf ("d=%Le\n", d);
393 printf ("x="); mpfr_dump (x);
394 printf ("e=%Le\n", e);
395 exit (1);
396 }
397 }
398 mpfr_clear (x);
399 }
400
401 /* issue reported by Sisyphus on powerpc */
402 static void
test_20140212(void)403 test_20140212 (void)
404 {
405 mpfr_t fr1, fr2;
406 long double ld, h, l, ld2;
407 int i, c1, c2;
408
409 mpfr_init2 (fr1, 106);
410 mpfr_init2 (fr2, 2098);
411
412 for (h = 1.0L, i = 0; i < 1023; i++)
413 h *= 2.0L;
414 for (l = 1.0L, i = 0; i < 1074; i++)
415 l *= 0.5L;
416 ld = h + l; /* rounding of 2^1023 + 2^(-1074) */
417
418 mpfr_set_ld (fr1, ld, MPFR_RNDN);
419 mpfr_set_ld (fr2, ld, MPFR_RNDN);
420
421 c1 = mpfr_cmp_ld (fr1, ld);
422 c2 = mpfr_cmp_ld (fr2, ld);
423
424 /* If long double is binary64, then ld = fr1 = fr2 = 2^1023.
425 If long double is double-double, then ld = 2^1023 + 2^(-1074),
426 fr1 = 2^1023 and fr2 = 2^1023 + 2^(-1074) */
427 MPFR_ASSERTN(ld == h ? (c1 == 0) : (c1 < 0));
428
429 MPFR_ASSERTN(c2 == 0);
430
431 ld2 = mpfr_get_ld (fr2, MPFR_RNDN);
432 MPFR_ASSERTN(ld2 == ld);
433
434 mpfr_clear (fr1);
435 mpfr_clear (fr2);
436 }
437
438 /* bug reported by Walter Mascarenhas
439 https://sympa.inria.fr/sympa/arc/mpfr/2016-09/msg00005.html */
440 static void
bug_20160907(void)441 bug_20160907 (void)
442 {
443 #if HAVE_LDOUBLE_IEEE_EXT_LITTLE
444 long double dn, ld;
445 mpfr_t mp;
446 long e;
447 mpfr_long_double_t x;
448
449 /* the following is the encoding of the smallest subnormal number
450 for HAVE_LDOUBLE_IEEE_EXT_LITTLE */
451 x.s.manl = 1;
452 x.s.manh = 0;
453 x.s.expl = 0;
454 x.s.exph = 0;
455 x.s.sign= 0;
456 dn = x.ld;
457 e = -16445;
458 /* dn=2^e is now the smallest subnormal. */
459
460 mpfr_init2 (mp, 64);
461 mpfr_set_ui_2exp (mp, 1, e - 1, MPFR_RNDN);
462 ld = mpfr_get_ld (mp, MPFR_RNDU);
463 /* since mp = 2^(e-1) and ld is rounded upwards, we should have
464 ld = 2^e */
465 if (ld != dn)
466 {
467 printf ("Error, ld = %Le <> dn = %Le\n", ld, dn);
468 printf ("mp=");
469 mpfr_out_str (stdout, 10, 0, mp, MPFR_RNDN);
470 printf ("\n");
471 printf ("mp="); mpfr_dump (mp);
472 exit (1);
473 }
474
475 /* check a few more numbers */
476 for (e = -16446; e <= -16381; e++)
477 {
478 mpfr_set_ui_2exp (mp, 1, e, MPFR_RNDN);
479 ld = mpfr_get_ld (mp, MPFR_RNDU);
480 mpfr_set_ld (mp, ld, MPFR_RNDU);
481 /* mp is 2^e rounded up, thus should be >= 2^e */
482 if (mpfr_cmp_ui_2exp (mp, 1, e) < 0)
483 {
484 if (tests_run_within_valgrind () && MPFR_IS_ZERO (mp))
485 {
486 /* Since this is not a bug in MPFR and it is just caused by
487 Valgrind, let's output a message and skip the remaining
488 part of the test without an error. Note that the message
489 will be not be visible via "make check".
490 Note that the other tests do not fail probably because
491 long double has the same behavior as double (which is
492 allowed by the C standard), but here this is a test that
493 is specific to x86 extended precision. */
494 printf
495 ("Error in bug_20160907 due to a bug in Valgrind.\n"
496 "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=890215\n"
497 "https://bugs.kde.org/show_bug.cgi?id=421262\n");
498 break;
499 }
500 printf ("Error, expected value >= 2^(%ld)\n", e);
501 printf ("got "); mpfr_dump (mp);
502 exit (1);
503 }
504
505 mpfr_set_ui_2exp (mp, 1, e, MPFR_RNDN);
506 ld = mpfr_get_ld (mp, MPFR_RNDD);
507 mpfr_set_ld (mp, ld, MPFR_RNDD);
508 /* mp is 2^e rounded down, thus should be <= 2^e */
509 if (mpfr_cmp_ui_2exp (mp, 1, e) > 0)
510 {
511 printf ("Error, expected value <= 2^(%ld)\n", e);
512 printf ("got "); mpfr_dump (mp);
513 exit (1);
514 }
515 }
516
517 mpfr_clear (mp);
518 #endif
519 }
520
521 int
main(int argc,char * argv[])522 main (int argc, char *argv[])
523 {
524 volatile long double d, e, maxp2;
525 mpfr_t x;
526 int i;
527 mpfr_exp_t emax;
528
529 tests_start_mpfr ();
530 mpfr_test_init ();
531
532 check_gcc33_bug ();
533 test_fixed_bugs ();
534
535 mpfr_init2 (x, MPFR_LDBL_MANT_DIG + 64);
536
537 #if !defined(MPFR_ERRDIVZERO)
538 /* check NaN */
539 mpfr_set_nan (x);
540 d = mpfr_get_ld (x, MPFR_RNDN);
541 check_set_get (d);
542 #endif
543
544 /* check +0.0 and -0.0 */
545 d = 0.0;
546 check_set_get (d);
547 d = DBL_NEG_ZERO;
548 check_set_get (d);
549
550 /* check that the sign of -0.0 is set */
551 mpfr_set_ld (x, DBL_NEG_ZERO, MPFR_RNDN);
552 if (MPFR_IS_POS (x))
553 {
554 #if defined(HAVE_SIGNEDZ)
555 printf ("Error: sign of -0.0 is not set correctly\n");
556 exit (1);
557 #else
558 /* Non IEEE doesn't support negative zero yet */
559 printf ("Warning: sign of -0.0 is not set correctly\n");
560 #endif
561 }
562
563 #if !defined(MPFR_ERRDIVZERO)
564 /* check +Inf */
565 mpfr_set_inf (x, 1);
566 d = mpfr_get_ld (x, MPFR_RNDN);
567 check_set_get (d);
568
569 /* check -Inf */
570 mpfr_set_inf (x, -1);
571 d = mpfr_get_ld (x, MPFR_RNDN);
572 check_set_get (d);
573 #endif
574
575 /* check the largest power of two */
576 maxp2 = 1.0;
577 while (maxp2 < LDBL_MAX / 2.0)
578 maxp2 *= 2.0;
579 check_set_get (maxp2);
580 check_set_get (-maxp2);
581
582 d = LDBL_MAX;
583 e = d / 2.0;
584 if (e != maxp2) /* false under NetBSD/x86 */
585 {
586 /* d = LDBL_MAX does not have excess precision. */
587 check_set_get (d);
588 check_set_get (-d);
589 }
590
591 /* check the smallest power of two */
592 d = 1.0;
593 while ((e = d / 2.0) != (long double) 0.0 && e != d)
594 d = e;
595 check_set_get (d);
596 check_set_get (-d);
597
598 /* check that 2^i, 2^i+1, 2^i-1 and 2^i-2^(i-2)-1 are correctly converted */
599 d = 1.0;
600 for (i = 1; i < MPFR_LDBL_MANT_DIG + 8; i++)
601 {
602 d = 2.0 * d; /* d = 2^i */
603 check_set_get (d);
604 if (d + 1.0 != d)
605 check_set_get (d + 1.0);
606 else
607 {
608 mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
609 mpfr_add_ui (x, x, 1, MPFR_RNDN);
610 e = mpfr_get_ld (x, MPFR_RNDN);
611 check_set_get (e);
612 }
613 if (d - 1.0 != d)
614 check_set_get (d - 1.0);
615 else
616 {
617 mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
618 mpfr_sub_ui (x, x, 1, MPFR_RNDN);
619 e = mpfr_get_ld (x, MPFR_RNDN);
620 check_set_get (e);
621 }
622 if (i < 3)
623 continue;
624 /* The following test triggers a failure in r10844 for i = 56,
625 with gcc -mpc64 on x86 (64-bit ABI). */
626 mpfr_set_ui_2exp (x, 3, i-2, MPFR_RNDN);
627 mpfr_sub_ui (x, x, 1, MPFR_RNDN);
628 e = mpfr_get_ld (x, MPFR_RNDN);
629 check_set_get (e);
630 }
631
632 for (i = 0; i < 10000; i++)
633 {
634 mpfr_urandomb (x, RANDS);
635 d = mpfr_get_ld (x, MPFR_RNDN);
636 check_set_get (d);
637 }
638
639 /* check with reduced emax to exercise overflow */
640 emax = mpfr_get_emax ();
641 mpfr_set_prec (x, 2);
642 set_emax (1);
643 mpfr_set_ld (x, (long double) 2.0, MPFR_RNDN);
644 MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
645 for (d = (long double) 2.0, i = 0; i < 13; i++, d *= d);
646 /* now d = 2^8192, or an infinity (e.g. with double or double-double) */
647 mpfr_set_ld (x, d, MPFR_RNDN);
648 MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
649 set_emax (emax);
650
651 mpfr_clear (x);
652
653 test_small ();
654
655 check_subnormal ();
656 #if !defined(MPFR_ERRDIVZERO)
657 check_overflow ();
658 #endif
659
660 test_20140212 ();
661 bug_20160907 ();
662
663 tests_end_mpfr ();
664
665 return 0;
666 }
667