xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tzeta.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* tzeta -- test file for the Riemann Zeta function
2 
3 Copyright 2003-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 static void
test1(void)26 test1 (void)
27 {
28   mpfr_t x, y;
29   int inex;
30 
31   mpfr_init2 (x, 32);
32   mpfr_init2 (y, 42);
33 
34   mpfr_clear_flags ();
35 
36   mpfr_set_str_binary (x, "1.1111111101000111011010010010100e-1");
37   mpfr_zeta (y, x, MPFR_RNDN); /* shouldn't crash */
38 
39   mpfr_set_prec (x, 40);
40   mpfr_set_prec (y, 50);
41   mpfr_set_str_binary (x, "1.001101001101000010011010110100110000101e-1");
42   mpfr_zeta (y, x, MPFR_RNDU);
43   mpfr_set_prec (x, 50);
44   mpfr_set_str_binary (x, "-0.11111100011100111111101111100011110111001111111111E1");
45   if (mpfr_cmp (x, y))
46     {
47       printf ("Error for input on 40 bits, output on 50 bits\n");
48       printf ("Expected "); mpfr_dump (x);
49       printf ("Got      "); mpfr_dump (y);
50       mpfr_set_str_binary (x, "1.001101001101000010011010110100110000101e-1");
51       mpfr_zeta (y, x, MPFR_RNDU);
52       mpfr_dump (x);
53       mpfr_dump (y);
54       exit (1);
55     }
56 
57   mpfr_set_prec (x, 2);
58   mpfr_set_prec (y, 55);
59   mpfr_set_str_binary (x, "0.11e3");
60   mpfr_zeta (y, x, MPFR_RNDN);
61   mpfr_set_prec (x, 55);
62   mpfr_set_str_binary (x, "0.1000001000111000010011000010011000000100100100100010010E1");
63   if (mpfr_cmp (x, y))
64     {
65       printf ("Error in mpfr_zeta (1)\n");
66       printf ("Expected "); mpfr_dump (x);
67       printf ("Got      "); mpfr_dump (y);
68       exit (1);
69     }
70 
71   mpfr_set_prec (x, 3);
72   mpfr_set_prec (y, 47);
73   mpfr_set_str_binary (x, "0.111e4");
74   mpfr_zeta (y, x, MPFR_RNDN);
75   mpfr_set_prec (x, 47);
76   mpfr_set_str_binary (x, "1.0000000000000100000000111001001010111100101011");
77   if (mpfr_cmp (x, y))
78     {
79       printf ("Error in mpfr_zeta (2)\n");
80       exit (1);
81     }
82 
83   /* coverage test */
84   mpfr_set_prec (x, 7);
85   mpfr_set_str_binary (x, "1.000001");
86   mpfr_set_prec (y, 2);
87   mpfr_zeta (y, x, MPFR_RNDN);
88   MPFR_ASSERTN(mpfr_cmp_ui (y, 64) == 0);
89 
90   /* another coverage test */
91   mpfr_set_prec (x, 24);
92   mpfr_set_ui (x, 2, MPFR_RNDN);
93   mpfr_set_prec (y, 2);
94   mpfr_zeta (y, x, MPFR_RNDN);
95   MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 3, -1) == 0);
96 
97   /* yet another coverage test (case beta <= 0.0) */
98   mpfr_set_prec (x, 10);
99   mpfr_set_ui (x, 23, MPFR_RNDN);
100   mpfr_set_prec (y, 15);
101   inex = mpfr_zeta (y, x, MPFR_RNDN);
102   MPFR_ASSERTN(inex < 0);
103   MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
104 
105   mpfr_set_inf (x, 1);
106   mpfr_zeta (y, x, MPFR_RNDN);
107   MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
108 
109   /* Since some tests don't really check that the result is not NaN... */
110   MPFR_ASSERTN (! mpfr_nanflag_p ());
111 
112   mpfr_set_inf (x, -1);
113   mpfr_zeta (y, x, MPFR_RNDN);
114   MPFR_ASSERTN(mpfr_nan_p (y));
115 
116   mpfr_set_nan (x);
117   mpfr_zeta (y, x, MPFR_RNDN);
118   MPFR_ASSERTN(mpfr_nan_p (y));
119 
120   mpfr_clear (x);
121   mpfr_clear (y);
122 }
123 
124 static const char *const val[] = {
125   "-2000", "0.0",
126   "-2.0", "0.0",
127   "-1.0", "-0.000101010101010101010101010101010101010101010101010101010101010",
128   "-0.9", "-0.000110011110011111010001010001100010111101001010100110001110110",
129   /*  "-0.8", "-0.000111110011101010001011100011010010000001010011110100010001110",
130   "-0.7", "-0.00100101011011111100110011110011111010111111000110110100010110",
131   "-0.6", "-0.00101100101100100100110111111000110010111010110010111000001100",
132   "-0.5", "-0.00110101001110000000100000011001100100010000111100010001111100",
133   "-0.4", "-0.00111111010001100011110001010010111110010001010101111101110001",
134   "-0.3", "-0.0100101100110111010101010100111011000001001010111010110101010",
135   "-0.2", "-0.0101100110000011101110101011011110101111000010000010110101111",
136   "-0.1", "-0.0110101011001111011101001111011000010001111010110011011111011",
137   "-0.0", "-0.100000000000000000000000000000000000000000000000000000000000",
138   "0.1", "-0.100110100110000010101010101110100000101100100011011001000101",
139   "0.2", "-0.10111011111000100011110111100010010001111010010010010100010110",
140   "0.3", "-0.11100111100100010011001000001011001100110010110101101110110110",
141   "0.4", "-1.0010001010000010000110111000100101001000001011101010110101011",
142   "0.5", "-1.0111010111011001110010110000011111100111001111111110111000110",
143   "0.6", "-1.1111001111100001100111101110010001001000001101100110110000100",
144   "0.7", "-10.110001110100010001110111000101010011110011000110010100101000",
145   "0.8", "-100.01110000000000101000010010000011000000111101100101100011010",
146   "0.9", "-1001.0110111000011011111100111100111011100010001111111010000100",
147   "0.99","-0.11000110110110001101011010110001011010011000110001011100101110E7",
148   "0.997", "-0.10100110011000001100111110011111100011110000111011101110001010E9",
149   "0.9995", "-0.11111001111011011000011110111111010111101001000110001111110010E11",
150   "0.99998", "-0.11000011010011110110110000111011101100001000101101011001110100E16",
151   "1.00001", "0.11000011010100000100100111100010001110100000110101110011111011E17",
152   "1.0002", "0.10011100010001001001111000101010111000011011011111110010110100E13",
153   "1.003","0.10100110111101001001010000000110101101110100001010100000110000E9",
154   "1.04", "11001.100101001000001011000111010110011010000001000010111101101",
155   "1.1", "1010.1001010110011110011010100010001100101001001111111101100001",
156   "1.2", "101.10010111011100011111001001100101101111110000110001101100010",
157   "1.3", "11.111011101001010000111001001110100100000101000101101011010100",
158   "1.4", "11.000110110000010100100101011110110001100001110100100100111111",
159   "1.5", "10.100111001100010010100001011111110111101100010011101011011100",
160   "1.6", "10.010010010010011111110000010011000110101001110011101010100110",
161   "1.7", "10.000011011110010111011110001100110010100010011100011111110010",
162   "1.8", "1.1110000111011001110011001101110101010000011011101100010111001",
163   "1.9", "1.1011111111101111011000011110001100100111100110111101101000101",
164   "2.0", "1.1010010100011010011001100010010100110000011111010011001000110",
165   "42.17", "1.0000000000000000000000000000000000000000001110001110001011001",
166   "-17.42", "-11.101110101010101000000001001000001111111101000100001100101100",
167   "-24.17", "-0.10001111010010011111000010001011111010010111101011000010010011E13"*/
168 };
169 
170 static void
test2(void)171 test2 (void)
172 {
173   mpfr_t x, y;
174   int i, n = numberof(val);
175 
176   mpfr_inits2 (55, x, y, (mpfr_ptr) 0);
177 
178   for(i = 0 ; i < n ; i+=2)
179     {
180       mpfr_set_str1 (x, val[i]);
181       mpfr_zeta(y, x, MPFR_RNDZ);
182       if (mpfr_cmp_str (y, val[i+1], 2, MPFR_RNDZ))
183         {
184           printf("Wrong result for zeta(%s=", val[i]);
185           mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
186           printf (").\nGot     : ");
187           mpfr_dump (y);
188           printf("Expected: ");
189           mpfr_set_str (y, val[i+1], 2, MPFR_RNDZ);
190           mpfr_dump (y);
191           mpfr_set_prec(y, 65);
192           mpfr_zeta(y, x, MPFR_RNDZ);
193           printf("+ Prec  : ");
194           mpfr_dump (y);
195           exit(1);
196         }
197     }
198   mpfr_clears (x, y, (mpfr_ptr) 0);
199 }
200 
201 /* The following test attempts to trigger an intermediate overflow in
202    Gamma(s1) in the reflection formula with a 32-bit ABI (the example
203    depends on the extended exponent range): r10804 fails when the
204    exponent field is on 32 bits. */
205 static void
intermediate_overflow(void)206 intermediate_overflow (void)
207 {
208   mpfr_t x, y1, y2;
209   mpfr_flags_t flags1, flags2;
210   int inex1, inex2;
211 
212   mpfr_inits2 (64, x, y1, y2, (mpfr_ptr) 0);
213 
214   mpfr_set_si (x, -44787928, MPFR_RNDN);
215   mpfr_nextabove (x);
216 
217   mpfr_set_str (y1, "0x3.0a6ab0ab281742acp+954986780", 0, MPFR_RNDN);
218   inex1 = -1;
219   flags1 = MPFR_FLAGS_INEXACT;
220 
221   mpfr_clear_flags ();
222   inex2 = mpfr_zeta (y2, x, MPFR_RNDN);
223   flags2 = __gmpfr_flags;
224 
225   if (!(mpfr_equal_p (y1, y2) &&
226         SAME_SIGN (inex1, inex2) &&
227         flags1 == flags2))
228     {
229       printf ("Error in intermediate_overflow\n");
230       printf ("Expected ");
231       mpfr_dump (y1);
232       printf ("with inex = %d and flags =", inex1);
233       flags_out (flags1);
234       printf ("Got      ");
235       mpfr_dump (y2);
236       printf ("with inex = %d and flags =", inex2);
237       flags_out (flags2);
238       exit (1);
239     }
240   mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
241 }
242 
243 #define TEST_FUNCTION mpfr_zeta
244 #define TEST_RANDOM_EMIN -48
245 #define TEST_RANDOM_EMAX 31
246 #include "tgeneric.c"
247 
248 /* Usage: tzeta - generic tests
249           tzeta s prec rnd_mode - compute zeta(s) with precision 'prec'
250                                   and rounding mode 'mode' */
251 int
main(int argc,char * argv[])252 main (int argc, char *argv[])
253 {
254   mpfr_t s, y, z;
255   mpfr_prec_t prec;
256   mpfr_rnd_t rnd_mode;
257   mpfr_flags_t flags;
258   int inex;
259 
260   tests_start_mpfr ();
261 
262   if (argc != 1 && argc != 4)
263     {
264       printf ("Usage: tzeta\n"
265               "    or tzeta s prec rnd_mode\n");
266       exit (1);
267     }
268 
269   if (argc == 4)
270     {
271       prec = atoi(argv[2]);
272       mpfr_init2 (s, prec);
273       mpfr_init2 (z, prec);
274       mpfr_set_str (s, argv[1], 10, MPFR_RNDN);
275       rnd_mode = (mpfr_rnd_t) atoi(argv[3]);
276 
277       mpfr_zeta (z, s, rnd_mode);
278       mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
279       printf ("\n");
280 
281       mpfr_clear (s);
282       mpfr_clear (z);
283 
284       return 0;
285     }
286 
287   test1();
288 
289   mpfr_init2 (s, MPFR_PREC_MIN);
290   mpfr_init2 (y, MPFR_PREC_MIN);
291   mpfr_init2 (z, MPFR_PREC_MIN);
292 
293 
294   /* the following seems to loop */
295   mpfr_set_prec (s, 6);
296   mpfr_set_prec (z, 6);
297   mpfr_set_str_binary (s, "1.10010e4");
298   mpfr_zeta (z, s, MPFR_RNDZ);
299 
300   mpfr_set_prec (s, 53);
301   mpfr_set_prec (y, 53);
302   mpfr_set_prec (z, 53);
303 
304   mpfr_set_ui (s, 1, MPFR_RNDN);
305   mpfr_clear_divby0();
306   mpfr_zeta (z, s, MPFR_RNDN);
307   if (!mpfr_inf_p (z) || MPFR_IS_NEG (z) || !mpfr_divby0_p())
308     {
309       printf ("Error in mpfr_zeta for s = 1 (should be +inf) with divby0 flag\n");
310       exit (1);
311     }
312 
313   mpfr_set_str_binary (s, "0.1100011101110111111111111010000110010111001011001011");
314   mpfr_set_str_binary (y, "-0.11111101111011001001001111111000101010000100000100100E2");
315   mpfr_zeta (z, s, MPFR_RNDN);
316   if (mpfr_cmp (z, y) != 0)
317     {
318       printf ("Error in mpfr_zeta (1,RNDN)\n");
319       exit (1);
320     }
321   mpfr_zeta (z, s, MPFR_RNDZ);
322   if (mpfr_cmp (z, y) != 0)
323     {
324       printf ("Error in mpfr_zeta (1,RNDZ)\n");
325       exit (1);
326     }
327   mpfr_zeta (z, s, MPFR_RNDU);
328   if (mpfr_cmp (z, y) != 0)
329     {
330       printf ("Error in mpfr_zeta (1,RNDU)\n");
331       exit (1);
332     }
333   mpfr_zeta (z, s, MPFR_RNDD);
334   mpfr_nexttoinf (y);
335   if (mpfr_cmp (z, y) != 0)
336     {
337       printf ("Error in mpfr_zeta (1,RNDD)\n");
338       exit (1);
339     }
340 
341   mpfr_set_str_binary (s, "0.10001011010011100110010001100100001011000010011001011");
342   mpfr_set_str_binary (y, "-0.11010011010010101101110111011010011101111101111010110E1");
343   mpfr_zeta (z, s, MPFR_RNDN);
344   if (mpfr_cmp (z, y) != 0)
345     {
346       printf ("Error in mpfr_zeta (2,RNDN)\n");
347       exit (1);
348     }
349   mpfr_zeta (z, s, MPFR_RNDZ);
350   if (mpfr_cmp (z, y) != 0)
351     {
352       printf ("Error in mpfr_zeta (2,RNDZ)\n");
353       exit (1);
354     }
355   mpfr_zeta (z, s, MPFR_RNDU);
356   if (mpfr_cmp (z, y) != 0)
357     {
358       printf ("Error in mpfr_zeta (2,RNDU)\n");
359       exit (1);
360     }
361   mpfr_zeta (z, s, MPFR_RNDD);
362   mpfr_nexttoinf (y);
363   if (mpfr_cmp (z, y) != 0)
364     {
365       printf ("Error in mpfr_zeta (2,RNDD)\n");
366       exit (1);
367     }
368 
369   mpfr_set_str_binary (s, "0.1100111110100001111110111000110101111001011101000101");
370   mpfr_set_str_binary (y, "-0.10010111010110000111011111001101100001111011000001010E3");
371   mpfr_zeta (z, s, MPFR_RNDN);
372   if (mpfr_cmp (z, y) != 0)
373     {
374       printf ("Error in mpfr_zeta (3,RNDN)\n");
375       exit (1);
376     }
377   mpfr_zeta (z, s, MPFR_RNDD);
378   if (mpfr_cmp (z, y) != 0)
379     {
380       printf ("Error in mpfr_zeta (3,RNDD)\n");
381       exit (1);
382     }
383   mpfr_nexttozero (y);
384   mpfr_zeta (z, s, MPFR_RNDZ);
385   if (mpfr_cmp (z, y) != 0)
386     {
387       printf ("Error in mpfr_zeta (3,RNDZ)\n");
388       exit (1);
389     }
390   mpfr_zeta (z, s, MPFR_RNDU);
391   if (mpfr_cmp (z, y) != 0)
392     {
393       printf ("Error in mpfr_zeta (3,RNDU)\n");
394       exit (1);
395     }
396 
397   mpfr_set_str (s, "-400000001", 10, MPFR_RNDZ);
398   mpfr_zeta (z, s, MPFR_RNDN);
399   if (!(mpfr_inf_p (z) && MPFR_IS_NEG (z)))
400     {
401       printf ("Error in mpfr_zeta (-400000001)\n");
402       exit (1);
403     }
404   mpfr_set_str (s, "-400000003", 10, MPFR_RNDZ);
405   mpfr_zeta (z, s, MPFR_RNDN);
406   if (!(mpfr_inf_p (z) && MPFR_IS_POS (z)))
407     {
408       printf ("Error in mpfr_zeta (-400000003)\n");
409       exit (1);
410     }
411 
412   mpfr_set_prec (s, 34);
413   mpfr_set_prec (z, 34);
414   mpfr_set_str_binary (s, "-1.111111100001011110000010001010000e-35");
415   mpfr_zeta (z, s, MPFR_RNDD);
416   mpfr_set_str_binary (s, "-1.111111111111111111111111111111111e-2");
417   if (mpfr_cmp (s, z))
418     {
419       printf ("Error in mpfr_zeta, prec=34, MPFR_RNDD\n");
420       mpfr_dump (z);
421       exit (1);
422     }
423 
424   /* bug found by nightly tests on June 7, 2007 */
425   mpfr_set_prec (s, 23);
426   mpfr_set_prec (z, 25);
427   mpfr_set_str_binary (s, "-1.0110110110001000000000e-27");
428   mpfr_zeta (z, s, MPFR_RNDN);
429   mpfr_set_prec (s, 25);
430   mpfr_set_str_binary (s, "-1.111111111111111111111111e-2");
431   if (mpfr_cmp (s, z))
432     {
433       printf ("Error in mpfr_zeta, prec=25, MPFR_RNDN\n");
434       printf ("expected "); mpfr_dump (s);
435       printf ("got      "); mpfr_dump (z);
436       exit (1);
437     }
438 
439   /* bug reported by Kevin Rauch on 26 Oct 2007 */
440   mpfr_set_prec (s, 128);
441   mpfr_set_prec (z, 128);
442   mpfr_set_str_binary (s, "-0.1000000000000000000000000000000000000000000000000000000000000001E64");
443   inex = mpfr_zeta (z, s, MPFR_RNDN);
444   MPFR_ASSERTN (mpfr_inf_p (z) && MPFR_IS_NEG (z) && inex < 0);
445   inex = mpfr_zeta (z, s, MPFR_RNDU);
446   mpfr_set_inf (s, -1);
447   mpfr_nextabove (s);
448   MPFR_ASSERTN (mpfr_equal_p (z, s) && inex > 0);
449 
450   /* bug reported by Fredrik Johansson on 19 Jan 2016 */
451   mpfr_set_prec (s, 536);
452   mpfr_set_ui_2exp (s, 1, -424, MPFR_RNDN);
453   mpfr_sub_ui (s, s, 128, MPFR_RNDN);  /* -128 + 2^(-424) */
454   for (prec = 6; prec <= 536; prec += 8) /* should go through 318 */
455     {
456       mpfr_set_prec (z, prec);
457       mpfr_zeta (z, s, MPFR_RNDD);
458       mpfr_set_prec (y, prec + 10);
459       mpfr_zeta (y, s, MPFR_RNDD);
460       mpfr_prec_round (y, prec, MPFR_RNDD);
461       if (! mpfr_equal_p (z, y))
462         {
463           printf ("mpfr_zeta fails near -128 for inprec=%lu outprec=%lu\n",
464                   (unsigned long) mpfr_get_prec (s), (unsigned long) prec);
465           printf ("expected "); mpfr_dump (y);
466           printf ("got      "); mpfr_dump (z);
467           exit (1);
468         }
469     }
470 
471   /* The following test yields an overflow in the error computation.
472      With r10864, this is detected and one gets an assertion failure. */
473   mpfr_set_prec (s, 1025);
474   mpfr_set_si_2exp (s, -1, 1024, MPFR_RNDN);
475   mpfr_nextbelow (s);  /* -(2^1024 + 1) */
476   mpfr_clear_flags ();
477   inex = mpfr_zeta (z, s, MPFR_RNDN);
478   flags = __gmpfr_flags;
479   if (flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT) ||
480       ! mpfr_inf_p (z) || MPFR_IS_POS (z) || inex >= 0)
481     {
482       printf ("Error in mpfr_zeta for s = -(2^1024 + 1)\nGot ");
483       mpfr_dump (z);
484       printf ("with inex = %d and flags =", inex);
485       flags_out (flags);
486       exit (1);
487     }
488 
489   mpfr_clear (s);
490   mpfr_clear (y);
491   mpfr_clear (z);
492 
493   /* FIXME: change the last argument back to 5 once the working precision
494      in the mpfr_zeta implementation no longer depends on the precision of
495      the input. */
496   test_generic (MPFR_PREC_MIN, 70, 1);
497   test2 ();
498 
499   intermediate_overflow ();
500 
501   tests_end_mpfr ();
502   return 0;
503 }
504