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