xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tgamma.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for gamma function
2 
3 Copyright 2001-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 "mpfr-test.h"
24 
25 /* Note: there could be an incorrect test about suspicious overflow
26    (MPFR_SUSPICIOUS_OVERFLOW) for x = 2^(-emax) = 0.5 * 2^(emin+1) in
27    RNDZ or RNDD, but this case is never tested in the generic tests. */
28 #define TEST_FUNCTION mpfr_gamma
29 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
30 #include "tgeneric.c"
31 
32 static void
special(void)33 special (void)
34 {
35   mpfr_t x, y;
36   int inex;
37 
38   mpfr_init (x);
39   mpfr_init (y);
40 
41   mpfr_set_nan (x);
42   mpfr_gamma (y, x, MPFR_RNDN);
43   if (!mpfr_nan_p (y))
44     {
45       printf ("Error for gamma(NaN)\n");
46       exit (1);
47     }
48 
49   mpfr_set_inf (x, -1);
50   mpfr_gamma (y, x, MPFR_RNDN);
51   if (!mpfr_nan_p (y))
52     {
53       printf ("Error for gamma(-Inf)\n");
54       exit (1);
55     }
56 
57   mpfr_set_inf (x, 1);
58   mpfr_gamma (y, x, MPFR_RNDN);
59   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
60     {
61       printf ("Error for gamma(+Inf)\n");
62       exit (1);
63     }
64 
65   mpfr_set_ui (x, 0, MPFR_RNDN);
66   mpfr_gamma (y, x, MPFR_RNDN);
67   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
68     {
69       printf ("Error for gamma(+0)\n");
70       exit (1);
71     }
72 
73   mpfr_set_ui (x, 0, MPFR_RNDN);
74   mpfr_neg (x, x, MPFR_RNDN);
75   mpfr_gamma (y, x, MPFR_RNDN);
76   if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
77     {
78       printf ("Error for gamma(-0)\n");
79       exit (1);
80     }
81 
82   mpfr_set_ui (x, 1, MPFR_RNDN);
83   mpfr_gamma (y, x, MPFR_RNDN);
84   if (mpfr_cmp_ui (y, 1))
85     {
86       printf ("Error for gamma(1)\n");
87       exit (1);
88     }
89 
90   mpfr_set_si (x, -1, MPFR_RNDN);
91   mpfr_gamma (y, x, MPFR_RNDN);
92   if (!mpfr_nan_p (y))
93     {
94       printf ("Error for gamma(-1)\n");
95       exit (1);
96     }
97 
98   mpfr_set_prec (x, 53);
99   mpfr_set_prec (y, 53);
100 
101 #define CHECK_X1 "1.0762904832837976166"
102 #define CHECK_Y1 "0.96134843256452096050"
103 
104   mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
105   mpfr_gamma (y, x, MPFR_RNDN);
106   mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
107   if (mpfr_cmp (y, x))
108     {
109       printf ("mpfr_lngamma(" CHECK_X1 ") is wrong:\n"
110               "expected ");
111       mpfr_dump (x);
112       printf ("got      ");
113       mpfr_dump (y);
114       exit (1);
115     }
116 
117 #define CHECK_X2 "9.23709516716202383435e-01"
118 #define CHECK_Y2 "1.0502315560291053398"
119   mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
120   mpfr_gamma (y, x, MPFR_RNDN);
121   mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
122   if (mpfr_cmp (y, x))
123     {
124       printf ("mpfr_lngamma(" CHECK_X2 ") is wrong:\n"
125               "expected ");
126       mpfr_dump (x);
127       printf ("got      ");
128       mpfr_dump (y);
129       exit (1);
130     }
131 
132   mpfr_set_prec (x, 8);
133   mpfr_set_prec (y, 175);
134   mpfr_set_ui (x, 33, MPFR_RNDN);
135   mpfr_gamma (y, x, MPFR_RNDU);
136   mpfr_set_prec (x, 175);
137   mpfr_set_str_binary (x, "0.110010101011010101101000010101010111000110011101001000101011000001100010111001101001011E118");
138   if (mpfr_cmp (x, y))
139     {
140       printf ("Error in mpfr_gamma (1)\n");
141       exit (1);
142     }
143 
144   mpfr_set_prec (x, 21);
145   mpfr_set_prec (y, 8);
146   mpfr_set_ui (y, 120, MPFR_RNDN);
147   mpfr_gamma (x, y, MPFR_RNDZ);
148   mpfr_set_prec (y, 21);
149   mpfr_set_str_binary (y, "0.101111101110100110110E654");
150   if (mpfr_cmp (x, y))
151     {
152       printf ("Error in mpfr_gamma (120)\n");
153       printf ("Expected "); mpfr_dump (y);
154       printf ("Got      "); mpfr_dump (x);
155       exit (1);
156     }
157 
158   mpfr_set_prec (x, 3);
159   mpfr_set_prec (y, 206);
160   mpfr_set_str_binary (x, "0.110e10");
161   inex = mpfr_gamma (y, x, MPFR_RNDN);
162   mpfr_set_prec (x, 206);
163   mpfr_set_str_binary (x, "0.110111100001000001101010010001000111000100000100111000010011100011011111001100011110101000111101101100110001001100110100001001111110000101010000100100011100010011101110000001000010001100010000101001111E6250");
164   if (mpfr_cmp (x, y))
165     {
166       printf ("Error in mpfr_gamma (768)\n");
167       exit (1);
168     }
169   if (inex <= 0)
170     {
171       printf ("Wrong flag for mpfr_gamma (768)\n");
172       exit (1);
173     }
174 
175   /* worst case to exercise retry */
176   mpfr_set_prec (x, 1000);
177   mpfr_set_prec (y, 869);
178   mpfr_const_pi (x, MPFR_RNDN);
179   mpfr_gamma (y, x, MPFR_RNDN);
180 
181   mpfr_set_prec (x, 4);
182   mpfr_set_prec (y, 4);
183   mpfr_set_str_binary (x, "-0.1100E-66");
184   mpfr_gamma (y, x, MPFR_RNDN);
185   mpfr_set_str_binary (x, "-0.1011E67");
186   if (mpfr_cmp (x, y))
187     {
188       printf ("Error for gamma(-0.1100E-66)\n");
189       exit (1);
190     }
191 
192   mpfr_set_prec (x, 2);
193   mpfr_set_prec (y, 2);
194   mpfr_set_ui (x, 2, MPFR_RNDN);
195   mpfr_clear_inexflag ();
196   mpfr_gamma (y, x, MPFR_RNDN);
197   if (mpfr_inexflag_p ())
198     {
199       printf ("Wrong inexact flag for gamma(2)\n");
200       printf ("expected 0, got 1\n");
201       exit (1);
202     }
203 
204   mpfr_clear (x);
205   mpfr_clear (y);
206 }
207 
208 static void
special_overflow(void)209 special_overflow (void)
210 {
211   mpfr_t x, y;
212   mpfr_exp_t emin, emax;
213   int inex;
214 
215   emin = mpfr_get_emin ();
216   emax = mpfr_get_emax ();
217 
218   set_emin (-125);
219   set_emax (128);
220 
221   mpfr_init2 (x, 24);
222   mpfr_init2 (y, 24);
223   mpfr_set_str_binary (x, "0.101100100000000000110100E7");
224   mpfr_gamma (y, x, MPFR_RNDN);
225   if (!mpfr_inf_p (y))
226     {
227       printf ("Overflow error.\n");
228       mpfr_dump (y);
229       exit (1);
230     }
231 
232   /* problem mentioned by Kenneth Wilder, 18 Aug 2005 */
233   mpfr_set_prec (x, 29);
234   mpfr_set_prec (y, 29);
235   mpfr_set_str (x, "-200000000.5", 10, MPFR_RNDN); /* exact */
236   mpfr_gamma (y, x, MPFR_RNDN);
237   if (!(mpfr_zero_p (y) && MPFR_IS_NEG (y)))
238     {
239       printf ("Error for gamma(-200000000.5)\n");
240       printf ("expected -0");
241       printf ("got      ");
242       mpfr_dump (y);
243       exit (1);
244     }
245 
246   mpfr_set_prec (x, 53);
247   mpfr_set_prec (y, 53);
248   mpfr_set_str (x, "-200000000.1", 10, MPFR_RNDN);
249   mpfr_gamma (y, x, MPFR_RNDN);
250   if (!(mpfr_zero_p (y) && MPFR_IS_NEG (y)))
251     {
252       printf ("Error for gamma(-200000000.1), prec=53\n");
253       printf ("expected -0");
254       printf ("got      ");
255       mpfr_dump (y);
256       exit (1);
257     }
258 
259   /* another problem mentioned by Kenneth Wilder, 29 Aug 2005 */
260   mpfr_set_prec (x, 333);
261   mpfr_set_prec (y, 14);
262   mpfr_set_str (x, "-2.0000000000000000000000005", 10, MPFR_RNDN);
263   mpfr_gamma (y, x, MPFR_RNDN);
264   mpfr_set_prec (x, 14);
265   mpfr_set_str_binary (x, "-11010011110001E66");
266   if (mpfr_cmp (x, y))
267     {
268       printf ("Error for gamma(-2.0000000000000000000000005)\n");
269       printf ("expected "); mpfr_dump (x);
270       printf ("got      "); mpfr_dump (y);
271       exit (1);
272     }
273 
274   /* another tests from Kenneth Wilder, 31 Aug 2005 */
275   set_emax (200);
276   set_emin (-200);
277   mpfr_set_prec (x, 38);
278   mpfr_set_prec (y, 54);
279   mpfr_set_str_binary (x, "0.11101111011100111101001001010110101001E-166");
280   mpfr_gamma (y, x, MPFR_RNDN);
281   mpfr_set_prec (x, 54);
282   mpfr_set_str_binary (x, "0.100010001101100001110110001010111111010000100101011E167");
283   if (mpfr_cmp (x, y))
284     {
285       printf ("Error for gamma (test 1)\n");
286       printf ("expected "); mpfr_dump (x);
287       printf ("got      "); mpfr_dump (y);
288       exit (1);
289     }
290 
291   set_emax (1000);
292   set_emin (-2000);
293   mpfr_set_prec (x, 38);
294   mpfr_set_prec (y, 71);
295   mpfr_set_str_binary (x, "10101011011100001111111000010111110010E-1034");
296   /* 184083777010*2^(-1034) */
297   mpfr_gamma (y, x, MPFR_RNDN);
298   mpfr_set_prec (x, 71);
299   mpfr_set_str_binary (x, "10111111001000011110010001000000000000110011110000000011101011111111100E926");
300   /* 1762885132679550982140*2^926 */
301   if (mpfr_cmp (x, y))
302     {
303       printf ("Error for gamma (test 2)\n");
304       printf ("expected "); mpfr_dump (x);
305       printf ("got      "); mpfr_dump (y);
306       exit (1);
307     }
308 
309   mpfr_set_prec (x, 38);
310   mpfr_set_prec (y, 88);
311   mpfr_set_str_binary (x, "10111100111001010000100001100100100101E-104");
312   /* 202824096037*2^(-104) */
313   mpfr_gamma (y, x, MPFR_RNDN);
314   mpfr_set_prec (x, 88);
315   mpfr_set_str_binary (x, "1010110101111000111010111100010110101010100110111000001011000111000011101100001101110010E-21");
316   /* 209715199999500283894743922*2^(-21) */
317   if (mpfr_cmp (x, y))
318     {
319       printf ("Error for gamma (test 3)\n");
320       printf ("expected "); mpfr_dump (x);
321       printf ("got      "); mpfr_dump (y);
322       exit (1);
323     }
324 
325   mpfr_set_prec (x, 171);
326   mpfr_set_prec (y, 38);
327   mpfr_set_str (x, "-2993155353253689176481146537402947624254601559176535", 10,
328                 MPFR_RNDN);
329   mpfr_div_2ui (x, x, 170, MPFR_RNDN);
330   mpfr_gamma (y, x, MPFR_RNDN);
331   mpfr_set_prec (x, 38);
332   mpfr_set_str (x, "201948391737", 10, MPFR_RNDN);
333   mpfr_mul_2ui (x, x, 92, MPFR_RNDN);
334   if (mpfr_cmp (x, y))
335     {
336       printf ("Error for gamma (test 5)\n");
337       printf ("expected "); mpfr_dump (x);
338       printf ("got      "); mpfr_dump (y);
339       exit (1);
340     }
341 
342   set_emin (-500000);
343   mpfr_set_prec (x, 337);
344   mpfr_set_prec (y, 38);
345   mpfr_set_str (x, "-30000.000000000000000000000000000000000000000000001", 10,
346                 MPFR_RNDN);
347   mpfr_gamma (y, x, MPFR_RNDN);
348   mpfr_set_prec (x, 38);
349   mpfr_set_str (x, "-3.623795987425E-121243", 10, MPFR_RNDN);
350   if (mpfr_cmp (x, y))
351     {
352       printf ("Error for gamma (test 7)\n");
353       printf ("expected "); mpfr_dump (x);
354       printf ("got      "); mpfr_dump (y);
355       exit (1);
356     }
357 
358   /* was producing infinite loop */
359   set_emin (emin);
360   mpfr_set_prec (x, 71);
361   mpfr_set_prec (y, 71);
362   mpfr_set_str (x, "-200000000.1", 10, MPFR_RNDN);
363   mpfr_gamma (y, x, MPFR_RNDN);
364   if (!(mpfr_zero_p (y) && MPFR_IS_NEG (y)))
365     {
366       printf ("Error for gamma (test 8)\n");
367       printf ("expected "); mpfr_dump (x);
368       printf ("got      "); mpfr_dump (y);
369       exit (1);
370     }
371 
372   set_emax (1073741821);
373   mpfr_set_prec (x, 29);
374   mpfr_set_prec (y, 29);
375   mpfr_set_str (x, "423786866", 10, MPFR_RNDN);
376   mpfr_gamma (y, x, MPFR_RNDN);
377   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
378     {
379       printf ("Error for gamma(423786866)\n");
380       exit (1);
381     }
382 
383   /* check exact result */
384   mpfr_set_prec (x, 2);
385   mpfr_set_ui (x, 3, MPFR_RNDN);
386   inex = mpfr_gamma (x, x, MPFR_RNDN);
387   if (inex != 0 || mpfr_cmp_ui (x, 2) != 0)
388     {
389       printf ("Error for gamma(3)\n");
390       exit (1);
391     }
392 
393   set_emax (1024);
394   mpfr_set_prec (x, 53);
395   mpfr_set_prec (y, 53);
396   mpfr_set_str_binary (x, "101010110100110011111010000110001000111100000110101E-43");
397   mpfr_gamma (x, x, MPFR_RNDU);
398   mpfr_set_str_binary (y, "110000011110001000111110110101011110000100001111111E971");
399   if (mpfr_cmp (x, y) != 0)
400     {
401       printf ("Error for gamma(4)\n");
402       printf ("expected "); mpfr_dump (y);
403       printf ("got      "); mpfr_dump (x);
404       exit (1);
405     }
406 
407   set_emin (emin);
408   set_emax (emax);
409 
410   /* bug found by Kevin Rauch, 26 Oct 2007 */
411   mpfr_set_str (x, "1e19", 10, MPFR_RNDN);
412   inex = mpfr_gamma (x, x, MPFR_RNDN);
413   MPFR_ASSERTN(mpfr_inf_p (x) && inex > 0);
414 
415   mpfr_clear (y);
416   mpfr_clear (x);
417 }
418 
419 /* test gamma on some integral values (from Christopher Creutzig). */
420 static void
gamma_integer(void)421 gamma_integer (void)
422 {
423   mpz_t n;
424   mpfr_t x, y;
425   unsigned int i;
426 
427   mpz_init (n);
428   mpfr_init2 (x, 149);
429   mpfr_init2 (y, 149);
430 
431   for (i = 0; i < 100; i++)
432     {
433       mpz_fac_ui (n, i);
434       mpfr_set_ui (x, i+1, MPFR_RNDN);
435       mpfr_gamma (y, x, MPFR_RNDN);
436       mpfr_set_z (x, n, MPFR_RNDN);
437       if (!mpfr_equal_p (x, y))
438         {
439           printf ("Error for gamma(%u)\n", i+1);
440           printf ("expected "); mpfr_dump (x);
441           printf ("got      "); mpfr_dump (y);
442           exit (1);
443         }
444     }
445   mpfr_clear (y);
446   mpfr_clear (x);
447   mpz_clear (n);
448 }
449 
450 /* bug found by Kevin Rauch */
451 static void
test20071231(void)452 test20071231 (void)
453 {
454   mpfr_t x;
455   int inex;
456   mpfr_exp_t emin;
457 
458   emin = mpfr_get_emin ();
459   set_emin (-1000000);
460 
461   mpfr_init2 (x, 21);
462   mpfr_set_str (x, "-1000001.5", 10, MPFR_RNDN);
463   inex = mpfr_gamma (x, x, MPFR_RNDN);
464   MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_POS(x) && inex < 0);
465   mpfr_clear (x);
466 
467   set_emin (emin);
468 
469   mpfr_init2 (x, 53);
470   mpfr_set_str (x, "-1000000001.5", 10, MPFR_RNDN);
471   inex = mpfr_gamma (x, x, MPFR_RNDN);
472   MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_POS(x) && inex < 0);
473   mpfr_clear (x);
474 }
475 
476 /* bug found by Stathis in mpfr_gamma, only occurs on 32-bit machines;
477    the second test is for 64-bit machines. This bug reappeared due to
478    r8159. */
479 static void
test20100709(void)480 test20100709 (void)
481 {
482   mpfr_t x, y, z;
483   int sign;
484   int inex;
485   mpfr_exp_t emin;
486 
487   mpfr_init2 (x, 100);
488   mpfr_init2 (y, 32);
489   mpfr_init2 (z, 32);
490   mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
491   mpfr_set_ui (y, 0, MPFR_RNDN);
492   mpfr_nextabove (y);
493   mpfr_log (y, y, MPFR_RNDD);
494   mpfr_const_log2 (z, MPFR_RNDU);
495   mpfr_sub (y, y, z, MPFR_RNDD); /* log(MIN/2) = log(MIN) - log(2) */
496   mpfr_lgamma (z, &sign, x, MPFR_RNDU);
497   MPFR_ASSERTN (sign == -1);
498   MPFR_ASSERTN (mpfr_less_p (z, y)); /* thus underflow */
499   inex = mpfr_gamma (x, x, MPFR_RNDN);
500   MPFR_ASSERTN (MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
501   mpfr_clear (x);
502   mpfr_clear (y);
503   mpfr_clear (z);
504 
505   /* Similar test for 64-bit machines (also valid with a 32-bit exponent,
506      but will not trigger the bug). */
507   emin = mpfr_get_emin ();
508   set_emin (MPFR_EMIN_MIN);
509   mpfr_init2 (x, 100);
510   mpfr_init2 (y, 32);
511   mpfr_init2 (z, 32);
512   mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN);
513   mpfr_set_ui (y, 0, MPFR_RNDN);
514   mpfr_nextabove (y);
515   mpfr_log (y, y, MPFR_RNDD);
516   mpfr_const_log2 (z, MPFR_RNDU);
517   mpfr_sub (y, y, z, MPFR_RNDD); /* log(MIN/2) = log(MIN) - log(2) */
518   mpfr_lgamma (z, &sign, x, MPFR_RNDU);
519   MPFR_ASSERTN (sign == -1);
520   MPFR_ASSERTN (mpfr_less_p (z, y)); /* thus underflow */
521   inex = mpfr_gamma (x, x, MPFR_RNDN);
522   MPFR_ASSERTN (MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
523   mpfr_clear (x);
524   mpfr_clear (y);
525   mpfr_clear (z);
526   set_emin (emin);
527 }
528 
529 /* bug found by Giridhar Tammana */
530 static void
test20120426(void)531 test20120426 (void)
532 {
533   mpfr_t xa, xb;
534   int i;
535   mpfr_exp_t emin;
536 
537   mpfr_init2 (xa, 53);
538   mpfr_init2 (xb, 53);
539   mpfr_set_si_2exp (xb, -337, -1, MPFR_RNDN);
540   emin = mpfr_get_emin ();
541   set_emin (-1073);
542   i = mpfr_gamma (xa, xb, MPFR_RNDN);
543   i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */
544   mpfr_set_str (xb, "-9.5737343987585366746184749943e-304", 10, MPFR_RNDN);
545   if (!((i > 0) && (mpfr_cmp (xa, xb) == 0)))
546     {
547       printf ("Error in test20120426, i=%d\n", i);
548       printf ("expected ");
549       mpfr_dump (xb);
550       printf ("got      ");
551       mpfr_dump (xa);
552       exit (1);
553     }
554   set_emin (emin);
555   mpfr_clear (xa);
556   mpfr_clear (xb);
557 }
558 
559 static void
exprange(void)560 exprange (void)
561 {
562   mpfr_exp_t emin, emax;
563   mpfr_t x, y, z;
564   int inex1, inex2;
565   unsigned int flags1, flags2;
566 
567   emin = mpfr_get_emin ();
568   emax = mpfr_get_emax ();
569 
570   mpfr_init2 (x, 16);
571   mpfr_inits2 (8, y, z, (mpfr_ptr) 0);
572 
573   mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
574   mpfr_clear_flags ();
575   inex1 = mpfr_gamma (y, x, MPFR_RNDN);
576   flags1 = __gmpfr_flags;
577   MPFR_ASSERTN (mpfr_inexflag_p ());
578   set_emin (0);
579   mpfr_clear_flags ();
580   inex2 = mpfr_gamma (z, x, MPFR_RNDN);
581   flags2 = __gmpfr_flags;
582   MPFR_ASSERTN (mpfr_inexflag_p ());
583   set_emin (emin);
584   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
585     {
586       printf ("Error in exprange (test1)\n");
587       printf ("x = ");
588       mpfr_dump (x);
589       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
590       mpfr_dump (y);
591       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
592       mpfr_dump (z);
593       exit (1);
594     }
595 
596   mpfr_set_ui_2exp (x, 32769, -60, MPFR_RNDN);
597   mpfr_clear_flags ();
598   inex1 = mpfr_gamma (y, x, MPFR_RNDD);
599   flags1 = __gmpfr_flags;
600   MPFR_ASSERTN (mpfr_inexflag_p ());
601   set_emax (45);
602   mpfr_clear_flags ();
603   inex2 = mpfr_gamma (z, x, MPFR_RNDD);
604   flags2 = __gmpfr_flags;
605   MPFR_ASSERTN (mpfr_inexflag_p ());
606   set_emax (emax);
607   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
608     {
609       printf ("Error in exprange (test2)\n");
610       printf ("x = ");
611       mpfr_dump (x);
612       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
613       mpfr_dump (y);
614       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
615       mpfr_dump (z);
616       exit (1);
617     }
618 
619   set_emax (44);
620   mpfr_clear_flags ();
621   inex1 = mpfr_check_range (y, inex1, MPFR_RNDD);
622   flags1 = __gmpfr_flags;
623   MPFR_ASSERTN (mpfr_inexflag_p ());
624   mpfr_clear_flags ();
625   inex2 = mpfr_gamma (z, x, MPFR_RNDD);
626   flags2 = __gmpfr_flags;
627   MPFR_ASSERTN (mpfr_inexflag_p ());
628   set_emax (emax);
629   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
630     {
631       printf ("Error in exprange (test3)\n");
632       printf ("x = ");
633       mpfr_dump (x);
634       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
635       mpfr_dump (y);
636       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
637       mpfr_dump (z);
638       exit (1);
639     }
640 
641   mpfr_set_ui_2exp (x, 1, -60, MPFR_RNDN);
642   mpfr_clear_flags ();
643   inex1 = mpfr_gamma (y, x, MPFR_RNDD);
644   flags1 = __gmpfr_flags;
645   MPFR_ASSERTN (mpfr_inexflag_p ());
646   set_emax (60);
647   mpfr_clear_flags ();
648   inex2 = mpfr_gamma (z, x, MPFR_RNDD);
649   flags2 = __gmpfr_flags;
650   MPFR_ASSERTN (mpfr_inexflag_p ());
651   set_emax (emax);
652   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
653     {
654       printf ("Error in exprange (test4)\n");
655       printf ("x = ");
656       mpfr_dump (x);
657       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
658       mpfr_dump (y);
659       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
660       mpfr_dump (z);
661       exit (1);
662     }
663 
664   MPFR_ASSERTN (MPFR_EMIN_MIN == - MPFR_EMAX_MAX);
665   set_emin (MPFR_EMIN_MIN);
666   set_emax (MPFR_EMAX_MAX);
667   mpfr_set_ui (x, 0, MPFR_RNDN);
668   mpfr_nextabove (x);  /* x = 2^(emin - 1) */
669   mpfr_set_inf (y, 1);
670   inex1 = 1;
671   flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
672   mpfr_clear_flags ();
673   /* MPFR_RNDU: overflow, infinity since 1/x = 2^(emax + 1) */
674   inex2 = mpfr_gamma (z, x, MPFR_RNDU);
675   flags2 = __gmpfr_flags;
676   MPFR_ASSERTN (mpfr_inexflag_p ());
677   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
678     {
679       printf ("Error in exprange (test5)\n");
680       printf ("x = ");
681       mpfr_dump (x);
682       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
683       mpfr_dump (y);
684       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
685       mpfr_dump (z);
686       exit (1);
687     }
688   mpfr_clear_flags ();
689   /* MPFR_RNDN: overflow, infinity since 1/x = 2^(emax + 1) */
690   inex2 = mpfr_gamma (z, x, MPFR_RNDN);
691   flags2 = __gmpfr_flags;
692   MPFR_ASSERTN (mpfr_inexflag_p ());
693   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
694     {
695       printf ("Error in exprange (test6)\n");
696       printf ("x = ");
697       mpfr_dump (x);
698       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
699       mpfr_dump (y);
700       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
701       mpfr_dump (z);
702       exit (1);
703     }
704   mpfr_nextbelow (y);
705   inex1 = -1;
706   mpfr_clear_flags ();
707   /* MPFR_RNDD: overflow, maxnum since 1/x = 2^(emax + 1) */
708   inex2 = mpfr_gamma (z, x, MPFR_RNDD);
709   flags2 = __gmpfr_flags;
710   MPFR_ASSERTN (mpfr_inexflag_p ());
711   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
712     {
713       printf ("Error in exprange (test7)\n");
714       printf ("x = ");
715       mpfr_dump (x);
716       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
717       mpfr_dump (y);
718       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
719       mpfr_dump (z);
720       exit (1);
721     }
722   mpfr_mul_2ui (x, x, 1, MPFR_RNDN);  /* x = 2^emin */
723   mpfr_set_inf (y, 1);
724   inex1 = 1;
725   flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
726   mpfr_clear_flags ();
727   /* MPFR_RNDU: overflow, infinity since 1/x = 2^emax */
728   inex2 = mpfr_gamma (z, x, MPFR_RNDU);
729   flags2 = __gmpfr_flags;
730   MPFR_ASSERTN (mpfr_inexflag_p ());
731   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
732     {
733       printf ("Error in exprange (test8)\n");
734       printf ("x = ");
735       mpfr_dump (x);
736       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
737       mpfr_dump (y);
738       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
739       mpfr_dump (z);
740       exit (1);
741     }
742   mpfr_clear_flags ();
743   /* MPFR_RNDN: overflow, infinity since 1/x = 2^emax */
744   inex2 = mpfr_gamma (z, x, MPFR_RNDN);
745   flags2 = __gmpfr_flags;
746   MPFR_ASSERTN (mpfr_inexflag_p ());
747   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
748     {
749       printf ("Error in exprange (test9)\n");
750       printf ("x = ");
751       mpfr_dump (x);
752       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
753       mpfr_dump (y);
754       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
755       mpfr_dump (z);
756       exit (1);
757     }
758   mpfr_nextbelow (y);
759   inex1 = -1;
760   flags1 = MPFR_FLAGS_INEXACT;
761   mpfr_clear_flags ();
762   /* MPFR_RNDD: no overflow, maxnum since 1/x = 2^emax and euler > 0 */
763   inex2 = mpfr_gamma (z, x, MPFR_RNDD);
764   flags2 = __gmpfr_flags;
765   MPFR_ASSERTN (mpfr_inexflag_p ());
766   if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
767     {
768       printf ("Error in exprange (test10)\n");
769       printf ("x = ");
770       mpfr_dump (x);
771       printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1);
772       mpfr_dump (y);
773       printf ("Got      inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2);
774       mpfr_dump (z);
775       exit (1);
776     }
777   set_emin (emin);
778   set_emax (emax);
779 
780   mpfr_clears (x, y, z, (mpfr_ptr) 0);
781 }
782 
783 static int
tiny_aux(int stop,mpfr_exp_t e)784 tiny_aux (int stop, mpfr_exp_t e)
785 {
786   mpfr_t x, y, z;
787   int r, s, spm, inex, err = 0;
788   int expected_dir[2][5] = { { 1, -1, 1, -1, 1 }, { 1, 1, 1, -1, -1 } };
789   mpfr_exp_t saved_emax;
790 
791   saved_emax = mpfr_get_emax ();
792 
793   mpfr_init2 (x, 32);
794   mpfr_inits2 (8, y, z, (mpfr_ptr) 0);
795 
796   mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN);
797   spm = 1;
798   for (s = 0; s < 2; s++)
799     {
800       RND_LOOP_NO_RNDF (r)
801         {
802           mpfr_rnd_t rr = (mpfr_rnd_t) r;
803           mpfr_exp_t exponent, emax;
804 
805           /* Exponent of the rounded value in unbounded exponent range. */
806           exponent = expected_dir[s][r] < 0 && s == 0 ? - e : 1 - e;
807 
808           for (emax = exponent - 1; emax <= exponent; emax++)
809             {
810               unsigned int flags, expected_flags = MPFR_FLAGS_INEXACT;
811               int overflow, expected_inex = expected_dir[s][r];
812 
813               if (emax > MPFR_EMAX_MAX)
814                 break;
815               set_emax (emax);
816 
817               mpfr_clear_flags ();
818               inex = mpfr_gamma (y, x, rr);
819               flags = __gmpfr_flags;
820               mpfr_clear_flags ();
821               mpfr_set_si_2exp (z, spm, - e, MPFR_RNDU);
822               overflow = mpfr_overflow_p ();
823               /* z is 1/x - euler rounded toward +inf */
824 
825               if (overflow && rr == MPFR_RNDN && s == 1)
826                 expected_inex = -1;
827 
828               if (expected_inex < 0)
829                 mpfr_nextbelow (z); /* 1/x - euler rounded toward -inf */
830 
831               if (exponent > emax)
832                 expected_flags |= MPFR_FLAGS_OVERFLOW;
833 
834               if (!(mpfr_equal_p (y, z) && flags == expected_flags
835                     && SAME_SIGN (inex, expected_inex)))
836                 {
837                   printf ("Error in tiny for s = %d, r = %s, emax = %"
838                           MPFR_EXP_FSPEC "d%s\n  on ",
839                           s, mpfr_print_rnd_mode (rr), (mpfr_eexp_t) emax,
840                           exponent > emax ? " (overflow)" : "");
841                   mpfr_dump (x);
842                   printf ("  expected inex = %2d, ", expected_inex);
843                   mpfr_dump (z);
844                   printf ("  got      inex = %2d, ", VSIGN (inex));
845                   mpfr_dump (y);
846                   printf ("  expected flags = %u, got %u\n",
847                           expected_flags, flags);
848                   if (stop)
849                     exit (1);
850                   err = 1;
851                 }
852             }
853         }
854       mpfr_neg (x, x, MPFR_RNDN);
855       spm = - spm;
856     }
857 
858   mpfr_clears (x, y, z, (mpfr_ptr) 0);
859   set_emax (saved_emax);
860   return err;
861 }
862 
863 static void
tiny(int stop)864 tiny (int stop)
865 {
866   mpfr_exp_t emin;
867   int err = 0;
868 
869   emin = mpfr_get_emin ();
870 
871   /* Note: in r7499, exponent -17 will select the generic code (in
872      tiny_aux, x has precision 32), while the other exponent values
873      will select special code for tiny values. */
874   err |= tiny_aux (stop, -17);
875   err |= tiny_aux (stop, -999);
876   err |= tiny_aux (stop, mpfr_get_emin ());
877 
878   if (emin != MPFR_EMIN_MIN)
879     {
880       set_emin (MPFR_EMIN_MIN);
881       err |= tiny_aux (stop, MPFR_EMIN_MIN);
882       set_emin (emin);
883     }
884 
885   if (err)
886     exit (1);
887 }
888 
889 /* Test mpfr_gamma in precision p1 by comparing it with exp(lgamma(x))
890    computing with a working precision p2. Assume that x is not an
891    integer <= 2. */
892 static void
exp_lgamma(mpfr_ptr x,mpfr_prec_t p1,mpfr_prec_t p2)893 exp_lgamma (mpfr_ptr x, mpfr_prec_t p1, mpfr_prec_t p2)
894 {
895   mpfr_t yd, yu, zd, zu;
896   int inexd, inexu, sign;
897   int underflow = -1, overflow = -1;  /* -1: we don't know */
898   int got_underflow, got_overflow;
899 
900   if (mpfr_integer_p (x) && mpfr_cmp_si (x, 2) <= 0)
901     {
902       printf ("Warning! x is an integer <= 2 in exp_lgamma: ");
903       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
904       return;
905     }
906   mpfr_inits2 (p2, yd, yu, (mpfr_ptr) 0);
907   inexd = mpfr_lgamma (yd, &sign, x, MPFR_RNDD);
908   mpfr_set (yu, yd, MPFR_RNDN);  /* exact */
909   if (inexd)
910     mpfr_nextabove (yu);
911   mpfr_clear_flags ();
912   mpfr_exp (yd, yd, MPFR_RNDD);
913   if (! mpfr_underflow_p ())
914     underflow = 0;
915   if (mpfr_overflow_p ())
916     overflow = 1;
917   mpfr_clear_flags ();
918   mpfr_exp (yu, yu, MPFR_RNDU);
919   if (mpfr_underflow_p ())
920     underflow = 1;
921   if (! mpfr_overflow_p ())
922     overflow = 0;
923   if (sign < 0)
924     {
925       mpfr_neg (yd, yd, MPFR_RNDN);  /* exact */
926       mpfr_neg (yu, yu, MPFR_RNDN);  /* exact */
927       mpfr_swap (yd, yu);
928     }
929   /* yd < Gamma(x) < yu (strict inequalities since x != 1 and x != 2) */
930   mpfr_inits2 (p1, zd, zu, (mpfr_ptr) 0);
931   mpfr_clear_flags ();
932   inexd = mpfr_gamma (zd, x, MPFR_RNDD);  /* zd <= Gamma(x) < yu */
933   got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p ();
934   got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p ();
935   if (! mpfr_less_p (zd, yu) || inexd > 0 ||
936       got_underflow != underflow ||
937       got_overflow != overflow)
938     {
939       printf ("Error in exp_lgamma on x = ");
940       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
941       printf ("yu = ");
942       mpfr_dump (yu);
943       printf ("zd = ");
944       mpfr_dump (zd);
945       printf ("got inexd = %d, expected <= 0\n", inexd);
946       printf ("got underflow = %d, expected %d\n", got_underflow, underflow);
947       printf ("got overflow = %d, expected %d\n", got_overflow, overflow);
948       exit (1);
949     }
950   mpfr_clear_flags ();
951   inexu = mpfr_gamma (zu, x, MPFR_RNDU);  /* zu >= Gamma(x) > yd */
952   got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p ();
953   got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p ();
954   if (! mpfr_greater_p (zu, yd) || inexu < 0 ||
955       got_underflow != underflow ||
956       got_overflow != overflow)
957     {
958       printf ("Error in exp_lgamma on x = ");
959       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
960       printf ("yd = ");
961       mpfr_dump (yd);
962       printf ("zu = ");
963       mpfr_dump (zu);
964       printf ("got inexu = %d, expected >= 0\n", inexu);
965       printf ("got underflow = %d, expected %d\n", got_underflow, underflow);
966       printf ("got overflow = %d, expected %d\n", got_overflow, overflow);
967       exit (1);
968     }
969   if (mpfr_equal_p (zd, zu))
970     {
971       if (inexd != 0 || inexu != 0)
972         {
973           printf ("Error in exp_lgamma on x = ");
974           mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
975           printf ("zd = zu, thus exact, but inexd = %d and inexu = %d\n",
976                   inexd, inexu);
977           exit (1);
978         }
979       MPFR_ASSERTN (got_underflow == 0);
980       MPFR_ASSERTN (got_overflow == 0);
981     }
982   else if (inexd == 0 || inexu == 0)
983     {
984       printf ("Error in exp_lgamma on x = ");
985           mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
986           printf ("zd != zu, thus inexact, but inexd = %d and inexu = %d\n",
987                   inexd, inexu);
988           exit (1);
989     }
990   mpfr_clears (yd, yu, zd, zu, (mpfr_ptr) 0);
991 }
992 
993 static void
exp_lgamma_tests(void)994 exp_lgamma_tests (void)
995 {
996   mpfr_t x;
997   mpfr_exp_t emin, emax;
998   int i;
999 
1000   emin = mpfr_get_emin ();
1001   emax = mpfr_get_emax ();
1002   set_emin (MPFR_EMIN_MIN);
1003   set_emax (MPFR_EMAX_MAX);
1004 
1005   mpfr_init2 (x, 96);
1006   for (i = 3; i <= 8; i++)
1007     {
1008       mpfr_set_ui (x, i, MPFR_RNDN);
1009       exp_lgamma (x, 53, 64);
1010       mpfr_nextbelow (x);
1011       exp_lgamma (x, 53, 64);
1012       mpfr_nextabove (x);
1013       mpfr_nextabove (x);
1014       exp_lgamma (x, 53, 64);
1015     }
1016   mpfr_set_str (x, "1.7", 10, MPFR_RNDN);
1017   exp_lgamma (x, 53, 64);
1018   mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
1019   exp_lgamma (x, 53, 64);
1020   mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN);
1021   exp_lgamma (x, 53, 64);
1022   /* The following test gives a large positive result < +Inf */
1023   mpfr_set_str (x, "1.2b13fc45a92dea1@14", 16, MPFR_RNDN);
1024   exp_lgamma (x, 53, 64);
1025   /* Idem for a large negative result > -Inf */
1026   mpfr_set_str (x, "-1.2b13fc45a92de81@14", 16, MPFR_RNDN);
1027   exp_lgamma (x, 53, 64);
1028   /* The following two tests trigger an endless loop in r8186
1029      on 64-bit machines (64-bit exponent). The second one (due
1030      to undetected overflow) is a direct consequence of the
1031      first one, due to the call of Gamma(2-x) if x < 1. */
1032   mpfr_set_str (x, "1.2b13fc45a92dec8@14", 16, MPFR_RNDN);
1033   exp_lgamma (x, 53, 64);
1034   mpfr_set_str (x, "-1.2b13fc45a92dea8@14", 16, MPFR_RNDN);
1035   exp_lgamma (x, 53, 64);
1036   /* Similar tests (overflow threshold) for 32-bit machines. */
1037   mpfr_set_str (x, "2ab68d8.657542f855111c61", 16, MPFR_RNDN);
1038   exp_lgamma (x, 12, 64);
1039   mpfr_set_str (x, "-2ab68d6.657542f855111c61", 16, MPFR_RNDN);
1040   exp_lgamma (x, 12, 64);
1041   /* The following test is an overflow on 32-bit and 64-bit machines.
1042      Revision r8189 fails on 64-bit machines as the flag is unset. */
1043   mpfr_set_str (x, "1.2b13fc45a92ded8@14", 16, MPFR_RNDN);
1044   exp_lgamma (x, 53, 64);
1045   /* On the following tests, with r8196, one gets an underflow on
1046      32-bit machines, while a normal result is expected (see FIXME
1047      in gamma.c:382). */
1048   mpfr_set_str (x, "-2ab68d6.657542f855111c6104", 16, MPFR_RNDN);
1049   exp_lgamma (x, 12, 64);  /* failure on 32-bit machines */
1050   mpfr_set_str (x, "-12b13fc45a92deb.1c6c5bc964", 16, MPFR_RNDN);
1051   exp_lgamma (x, 12, 64);  /* failure on 64-bit machines */
1052   mpfr_clear (x);
1053 
1054   set_emin (emin);
1055   set_emax (emax);
1056 }
1057 
1058 /* Bug reported by Frithjof Blomquist on May 19, 2020.
1059    For the record, this bug was present since r8981
1060    (in mpfr_bernoulli_internal, den was wrongly reset to 1 in case
1061    of failure in Ziv's loop). The bug only occurred up from r8986
1062    where the initial precision was reduced, but was potentially
1063    present in any case of failure of Ziv's loop. */
1064 static void
bug20200519(void)1065 bug20200519 (void)
1066 {
1067   mpfr_prec_t prec = 25093;
1068   mpfr_t x, y, z, d;
1069   double dd;
1070   size_t min_memory_limit, old_memory_limit;
1071 
1072   old_memory_limit = tests_memory_limit;
1073   min_memory_limit = 24000000;
1074   if (tests_memory_limit > 0 && tests_memory_limit < min_memory_limit)
1075     tests_memory_limit = min_memory_limit;
1076 
1077   mpfr_init2 (x, prec);
1078   mpfr_init2 (y, prec);
1079   mpfr_init2 (z, prec + 100);
1080   mpfr_init2 (d, 24);
1081   mpfr_set_d (x, 2.5, MPFR_RNDN);
1082   mpfr_gamma (y, x, MPFR_RNDN);
1083   mpfr_gamma (z, x, MPFR_RNDN);
1084   mpfr_sub (d, y, z, MPFR_RNDN);
1085   mpfr_mul_2si (d, d, prec - mpfr_get_exp (y), MPFR_RNDN);
1086   dd = mpfr_get_d (d, MPFR_RNDN);
1087   if (dd < -0.5 || 0.5 < dd)
1088     {
1089       printf ("Error in bug20200519: dd=%f\n", dd);
1090       exit (1);
1091     }
1092   mpfr_clear (x);
1093   mpfr_clear (y);
1094   mpfr_clear (z);
1095   mpfr_clear (d);
1096 
1097   tests_memory_limit = old_memory_limit;
1098 }
1099 
1100 int
main(int argc,char * argv[])1101 main (int argc, char *argv[])
1102 {
1103   tests_start_mpfr ();
1104 
1105   if (argc == 3) /* tgamma x prec: print gamma(x) to prec bits */
1106     {
1107       mpfr_prec_t p = atoi (argv[2]);
1108       mpfr_t x;
1109       mpfr_init2 (x, p);
1110       mpfr_set_str (x, argv[1], 10, MPFR_RNDN);
1111       mpfr_gamma (x, x, MPFR_RNDN);
1112       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1113       printf ("\n");
1114       mpfr_clear (x);
1115       return 0;
1116     }
1117 
1118   special ();
1119   special_overflow ();
1120   exprange ();
1121   tiny (argc == 1);
1122   test_generic (MPFR_PREC_MIN, 100, 2);
1123   gamma_integer ();
1124   test20071231 ();
1125   test20100709 ();
1126   test20120426 ();
1127   exp_lgamma_tests ();
1128 
1129   data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
1130 
1131   /* this test takes about one minute */
1132   if (getenv ("MPFR_CHECK_EXPENSIVE") != NULL &&
1133       getenv ("MPFR_CHECK_LARGEMEM") != NULL)
1134     bug20200519 ();
1135 
1136   tests_end_mpfr ();
1137   return 0;
1138 }
1139