xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tatan.c (revision 17dc1ceb5c5ff563444a48bf21025d7ddee5f8d2)
1 /* Test file for mpfr_atan and mpfr_atan2.
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 static void
special(void)26 special (void)
27 {
28   mpfr_t x, y, z;
29   int r;
30   int i;
31 
32   mpfr_init2 (x, 53);
33   mpfr_init2 (y, 53);
34   mpfr_init2 (z, 53);
35 
36   mpfr_set_str_binary (x, "1.0000100110000001100111100011001110101110100111011101");
37   mpfr_set_str_binary (y, "1.1001101101110100101100110011011101101000011010111110e-1");
38   mpfr_atan (z, x, MPFR_RNDN);
39   if (mpfr_cmp (y, z))
40     {
41       printf ("Error in mpfr_atan for prec=53, rnd=MPFR_RNDN\n");
42       printf ("x=");
43       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
44       printf ("\nexpected ");
45       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
46       printf ("\ngot      ");
47       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
48       printf ("\n");
49       exit (1);
50     }
51 
52   /* atan(+Inf) = Pi/2 */
53   RND_LOOP (r)
54     {
55       mpfr_set_inf (x, 1);
56       mpfr_atan (y, x, (mpfr_rnd_t) r);
57       mpfr_const_pi (x, (mpfr_rnd_t) r);
58       mpfr_div_2ui (x, x, 1, (mpfr_rnd_t) r);
59       if (mpfr_cmp (x, y))
60         {
61           printf ("Error: mpfr_atan(+Inf), rnd=%s\n",
62                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
63           exit (1);
64         }
65     }
66 
67   /* atan(-Inf) = - Pi/2 */
68   RND_LOOP (r)
69     {
70       mpfr_set_inf (x, -1);
71       mpfr_atan (y, x, (mpfr_rnd_t) r);
72       mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
73       mpfr_neg (x, x, (mpfr_rnd_t) r);
74       mpfr_div_2ui (x, x, 1, (mpfr_rnd_t) r);
75       if (mpfr_cmp (x, y))
76         {
77           printf ("Error: mpfr_atan(-Inf), rnd=%s\n",
78                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
79           exit (1);
80         }
81     }
82 
83   /* atan(NaN) = NaN */
84   mpfr_set_nan (x);
85   mpfr_atan (y, x, MPFR_RNDN);
86   if (!mpfr_nan_p (y))
87     {
88       printf ("Error: mpfr_atan(NaN) <> NaN\n");
89       exit (1);
90     }
91 
92   /* atan(+/-0) = +/-0 */
93   mpfr_set_ui (x, 0, MPFR_RNDN);
94   MPFR_SET_NEG (y);
95   mpfr_atan (y, x, MPFR_RNDN);
96   if (mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
97     {
98       printf ("Error: mpfr_atan (+0) <> +0\n");
99       exit (1);
100     }
101   mpfr_atan (x, x, MPFR_RNDN);
102   if (mpfr_cmp_ui (x, 0) || MPFR_IS_NEG (x))
103     {
104       printf ("Error: mpfr_atan (+0) <> +0 (in place)\n");
105       exit (1);
106     }
107   mpfr_neg (x, x, MPFR_RNDN);
108   MPFR_SET_POS (y);
109   mpfr_atan (y, x, MPFR_RNDN);
110   if (mpfr_cmp_ui (y, 0) || MPFR_IS_POS (y))
111     {
112       printf ("Error: mpfr_atan (-0) <> -0\n");
113       exit (1);
114     }
115   mpfr_atan (x, x, MPFR_RNDN);
116   if (mpfr_cmp_ui (x, 0) || MPFR_IS_POS (x))
117     {
118       printf ("Error: mpfr_atan (-0) <> -0 (in place)\n");
119       exit (1);
120     }
121 
122   mpfr_set_prec (x, 32);
123   mpfr_set_prec (y, 32);
124 
125   /* test one random positive argument */
126   mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
127   mpfr_atan (x, x, MPFR_RNDN);
128   mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1");
129   if (mpfr_cmp (x, y))
130     {
131       printf ("Error in mpfr_atan (1)\n");
132       exit (1);
133     }
134 
135   /* test one random negative argument */
136   mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
137   mpfr_atan (x, x, MPFR_RNDN);
138   mpfr_set_str_binary (y, "-0.101001110001010010110001110001");
139   if (mpfr_cmp (x, y))
140     {
141       printf ("Error in mpfr_atan (2)\n");
142       mpfr_dump (x);
143       mpfr_dump (y);
144       exit (1);
145     }
146 
147   mpfr_set_prec (x, 3);
148   mpfr_set_prec (y, 192);
149   mpfr_set_prec (z, 192);
150   mpfr_set_str_binary (x, "-0.100e1");
151   mpfr_atan (z, x, MPFR_RNDD);
152   mpfr_set_str_binary (y, "-0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110000011100110100010010100100000010010011100000100010001010011001111100110001110101");
153   if (mpfr_cmp (z, y))
154     {
155       printf ("Error in mpfr_atan (3)\n");
156       printf ("Expected "); mpfr_dump (y);
157       printf ("Got      "); mpfr_dump (z);
158       exit (1);
159     }
160 
161   /* Test regression */
162   mpfr_set_prec (x, 51);
163   mpfr_set_prec (y, 51);
164   mpfr_set_str_binary (x,
165            "0.101100100000101111111010001111111000001000000000000E-11");
166   i = mpfr_atan (y, x, MPFR_RNDN);
167   if (mpfr_cmp_str (y,
168    "1.01100100000101111111001110011001010110100100000000e-12", 2, MPFR_RNDN)
169       || i >= 0)
170     {
171       printf ("Wrong Regression test (%d)\n", i);
172       mpfr_dump (y);
173       exit (1);
174     }
175 
176   mpfr_set_si (x, -1, MPFR_RNDN);
177   mpfr_atan (x, x, MPFR_RNDN);
178   MPFR_ASSERTN (MPFR_IS_NEG (x));
179 
180   /* Test regression */
181   mpfr_set_prec (x, 48);
182   mpfr_set_prec (y, 48);
183   mpfr_set_str_binary (x, "1.11001110010000011111100000010000000000000000000e-19");
184   mpfr_atan (y, x, MPFR_RNDD);
185   if (mpfr_cmp_str (y, "0.111001110010000011111100000001111111110000010011E-18", 2, MPFR_RNDN))
186     {
187       printf ("Error in mpfr_atan (4)\n");
188       printf ("Input    1.11001110010000011111100000010000000000000000000e-19 [prec=48]\n");
189       printf ("Expected 0.111001110010000011111100000001111111110000010011E-18\n");
190       printf ("Got      "); mpfr_dump (y);
191       exit (1);
192     }
193 
194   mpfr_clear (x);
195   mpfr_clear (y);
196   mpfr_clear (z);
197 }
198 
199 #define TEST_FUNCTION mpfr_atan
200 #define test_generic test_generic_atan
201 #define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), mpfr_mul_2si (x, x, (randlimb () %1000-500), MPFR_RNDN))
202 #include "tgeneric.c"
203 
204 #define TEST_FUNCTION mpfr_atan2
205 #define TWO_ARGS
206 #define test_generic test_generic_atan2
207 #include "tgeneric.c"
208 
209 #define TEST_FUNCTION mpfr_atan2
210 #define TWO_ARGS
211 #define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), MPFR_SET_NEG (x))
212 #define test_generic test_generic_atan2_neg
213 #include "tgeneric.c"
214 
215 static void
special_overflow(void)216 special_overflow (void)
217 {
218   mpfr_t x, y;
219   mpfr_exp_t emin, emax;
220 
221   emin = mpfr_get_emin ();
222   emax = mpfr_get_emax ();
223 
224   set_emin (-125);
225   set_emax (128);
226   mpfr_init2 (x, 24);
227   mpfr_init2 (y, 48);
228   mpfr_set_str_binary (x, "0.101101010001001101111010E0");
229   mpfr_atan (y, x, MPFR_RNDN);
230   if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0",
231                     2, MPFR_RNDN))
232     {
233       printf("Special Overflow error.\n");
234       mpfr_dump (y);
235       exit (1);
236     }
237 
238   /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */
239   set_emax (1);
240   mpfr_set_inf (x, +1);
241   mpfr_clear_flags ();
242   mpfr_atan (y, x, MPFR_RNDN);
243   if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN)
244       || mpfr_overflow_p ())
245     {
246       printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n",
247              (long int) mpfr_get_emax ());
248       mpfr_dump (y);
249       exit (1);
250     }
251 
252   /* atan(+Inf) = Pi/2 underflows */
253   set_emax (128);
254   set_emin (3);
255   mpfr_clear_flags ();
256   mpfr_atan (y, x, MPFR_RNDN);
257   if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
258     {
259       printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n",
260              (long int) mpfr_get_emin ());
261       mpfr_dump (y);
262       exit (1);
263     }
264 
265   /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */
266   set_emax (1);
267   set_emin (-128);
268   mpfr_set_ui (x, 1, MPFR_RNDN);
269   mpfr_clear_flags ();
270   mpfr_atan (y, x, MPFR_RNDN);
271   if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN)
272       || mpfr_overflow_p ())
273     {
274       printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n",
275              (long int) mpfr_get_emax ());
276       mpfr_dump (y);
277       exit (1);
278     }
279 
280   /* atan(+1) = Pi/4 underflows and is rounded up to 1 */
281   set_emax (128);
282   set_emin (1);
283   mpfr_set_prec (y, 2);
284   mpfr_clear_flags ();
285   mpfr_atan (y, x, MPFR_RNDN);
286   if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ())
287     {
288       printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
289              (long int) mpfr_get_emin ());
290       mpfr_dump (y);
291       exit (1);
292     }
293 
294   /* atan(+1) = Pi/4 underflows and is rounded down to 0 */
295   mpfr_clear_flags ();
296   mpfr_atan (y, x, MPFR_RNDD);
297   if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
298     {
299       printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
300              (long int) mpfr_get_emin ());
301       mpfr_dump (y);
302       exit (1);
303     }
304 
305   mpfr_clear (y);
306   mpfr_clear (x);
307   set_emin (emin);
308   set_emax (emax);
309 }
310 
311 static void
special_atan2(void)312 special_atan2 (void)
313 {
314   mpfr_t x, y, z;
315 
316   mpfr_inits2 (4, x, y, z, (mpfr_ptr) 0);
317 
318   /* Anything with NAN should be set to NAN */
319   mpfr_set_ui (y, 0, MPFR_RNDN);
320   mpfr_set_nan (x);
321   mpfr_atan2 (z, y, x, MPFR_RNDN);
322   MPFR_ASSERTN (MPFR_IS_NAN (z));
323   mpfr_swap (x, y);
324   mpfr_atan2 (z, y, x, MPFR_RNDN);
325   MPFR_ASSERTN (MPFR_IS_NAN (z));
326 
327   /* 0+ 0+ --> 0+ */
328   mpfr_set_ui (y, 0, MPFR_RNDN);
329   mpfr_atan2 (z, y, x, MPFR_RNDN);
330   MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
331   /* 0- 0+ --> 0- */
332   MPFR_CHANGE_SIGN (y);
333   mpfr_atan2 (z, y, x, MPFR_RNDN);
334   MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
335   /* 0- 0- --> -PI */
336   MPFR_CHANGE_SIGN (x);
337   mpfr_atan2 (z, y, x, MPFR_RNDN);
338   MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
339   /* 0+ 0- --> +PI */
340   MPFR_CHANGE_SIGN (y);
341   mpfr_atan2 (z, y, x, MPFR_RNDN);
342   MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
343   /* 0+ -1 --> PI */
344   mpfr_set_si (x, -1, MPFR_RNDN);
345   mpfr_atan2 (z, y, x, MPFR_RNDN);
346   MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
347   /* 0- -1 --> -PI */
348   MPFR_CHANGE_SIGN (y);
349   mpfr_atan2 (z, y, x, MPFR_RNDN);
350   MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
351   /* 0- +1 --> 0- */
352   mpfr_set_ui (x, 1, MPFR_RNDN);
353   mpfr_atan2 (z, y, x, MPFR_RNDN);
354   MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
355   /* 0+ +1 --> 0+ */
356   MPFR_CHANGE_SIGN (y);
357   mpfr_atan2 (z, y, x, MPFR_RNDN);
358   MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
359   /* +1 0+ --> PI/2 */
360   mpfr_swap (x, y);
361   mpfr_atan2 (z, y, x, MPFR_RNDN);
362   MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
363   /* +1 0- --> PI/2 */
364   MPFR_CHANGE_SIGN (x);
365   mpfr_atan2 (z, y, x, MPFR_RNDN);
366   MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
367   /* -1 0- --> -PI/2 */
368   MPFR_CHANGE_SIGN (y);
369   mpfr_atan2 (z, y, x, MPFR_RNDN);
370   MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
371   /* -1 0+ --> -PI/2 */
372   MPFR_CHANGE_SIGN (x);
373   mpfr_atan2 (z, y, x, MPFR_RNDN);
374   MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
375 
376   /* -1 +INF --> -0 */
377   MPFR_SET_INF (x);
378   mpfr_atan2 (z, y, x, MPFR_RNDN);
379   MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
380   /* +1 +INF --> +0 */
381   MPFR_CHANGE_SIGN (y);
382   mpfr_atan2 (z, y, x, MPFR_RNDN);
383   MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
384   /* +1 -INF --> +PI */
385   MPFR_CHANGE_SIGN (x);
386   mpfr_atan2 (z, y, x, MPFR_RNDN);
387   MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
388   /* -1 -INF --> -PI */
389   MPFR_CHANGE_SIGN (y);
390   mpfr_atan2 (z, y, x, MPFR_RNDN);
391   MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
392   /* -INF -1 --> -PI/2 */
393   mpfr_swap (x, y);
394   mpfr_atan2 (z, y, x, MPFR_RNDN);
395   MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
396   /* +INF -1  --> PI/2 */
397   MPFR_CHANGE_SIGN (y);
398   mpfr_atan2 (z, y, x, MPFR_RNDN);
399   MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
400   /* +INF -INF --> 3*PI/4 */
401   MPFR_SET_INF (x);
402   mpfr_atan2 (z, y, x, MPFR_RNDN);
403   MPFR_ASSERTN (mpfr_cmp_str (z, "2.356194490192344928", 10, MPFR_RNDN) == 0);
404   /* +INF +INF --> PI/4 */
405   MPFR_CHANGE_SIGN (x);
406   mpfr_atan2 (z, y, x, MPFR_RNDN);
407   MPFR_ASSERTN (mpfr_cmp_str (z, "0.785375", 10, MPFR_RNDN) == 0);
408   /* -INF +INF --> -PI/4 */
409   MPFR_CHANGE_SIGN (y);
410   mpfr_atan2 (z, y, x, MPFR_RNDN);
411   MPFR_ASSERTN (mpfr_cmp_str (z, "-0.785375", 10, MPFR_RNDN) == 0);
412   /* -INF -INF --> -3*PI/4 */
413   MPFR_CHANGE_SIGN (x);
414   mpfr_atan2 (z, y, x, MPFR_RNDN);
415   MPFR_ASSERTN (mpfr_cmp_str (z, "-2.356194490192344928", 10, MPFR_RNDN) == 0);
416   mpfr_set_prec (z, 905); /* exercises Ziv's loop */
417   mpfr_atan2 (z, y, x, MPFR_RNDZ);
418   MPFR_ASSERTN (mpfr_cmp_str (z, "-2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488496172998532038345716293667379401955609636083808771307702645389082916973346721171619778647332160823174945008459635673617534008737395340143185923642519259526145784", 10, MPFR_RNDN) == 0);
419 
420   mpfr_clears (x, y, z, (mpfr_ptr) 0);
421 }
422 
423 /* from Christopher Creutzig, 18 Jul 2007 */
424 static void
smallvals_atan2(void)425 smallvals_atan2 (void)
426 {
427   mpfr_t a, x, y;
428   mpfr_exp_t old_emin;
429 
430   mpfr_inits (a, x, y, (mpfr_ptr) 0);
431   mpfr_set_ui (y, 0, MPFR_RNDN);
432   mpfr_nextbelow (y);
433   mpfr_set_ui (x, 1, MPFR_RNDN);
434   /* y=-2^(-emin-1), x=1 */
435 
436   mpfr_atan2 (a, y, x, MPFR_RNDD);
437   MPFR_ASSERTN (mpfr_equal_p (a, y));
438 
439   mpfr_atan2 (a, y, x, MPFR_RNDU);
440   MPFR_ASSERTN (mpfr_zero_p (a) && MPFR_IS_NEG(a));
441 
442   mpfr_set_prec (x, 8);
443   mpfr_set_prec (y, 8);
444   mpfr_set_prec (a, 8);
445   old_emin = mpfr_get_emin ();
446   set_emin (MPFR_EMIN_MIN);
447 
448   mpfr_set_si (y, 3, MPFR_RNDN);
449   mpfr_set_exp (y, mpfr_get_emin ());
450   mpfr_set_str_binary (x, "1.1");
451   mpfr_atan2 (a, y, x, MPFR_RNDU);
452   mpfr_set_si (y, 1, MPFR_RNDN);
453   mpfr_set_exp (y, mpfr_get_emin ());
454   MPFR_ASSERTN (mpfr_equal_p (a, y));
455 
456   /* From a bug reported by Christopher Creutzig on 2007-08-28.
457      Added test in each rounding mode.
458      Segmentation fault or assertion failure due to an infinite Ziv loop. */
459   mpfr_set_si (y, 1, MPFR_RNDN);
460   mpfr_set_exp (y, mpfr_get_emin ());
461   mpfr_set_str_binary (x, "1.01");
462   mpfr_atan2 (a, y, x, MPFR_RNDZ);
463   MPFR_ASSERTN (mpfr_zero_p (a));
464   mpfr_atan2 (a, y, x, MPFR_RNDD);
465   MPFR_ASSERTN (mpfr_zero_p (a));
466   mpfr_atan2 (a, y, x, MPFR_RNDU);
467   MPFR_ASSERTN (mpfr_equal_p (a, y));
468   mpfr_atan2 (a, y, x, MPFR_RNDN);
469   MPFR_ASSERTN (mpfr_equal_p (a, y));
470 
471   /* trigger underflow with rounding to nearest */
472   mpfr_set_ui (x, 4, MPFR_RNDN);
473   mpfr_atan2 (a, y, x, MPFR_RNDN);
474   MPFR_ASSERTN (mpfr_zero_p (a));
475 
476   set_emin (old_emin);
477 
478   mpfr_clears (a, x, y, (mpfr_ptr) 0);
479 }
480 
481 /* Bug found by Robert Bajema (regression in MPFR 2.3.0).
482    The cause is the underflow flag set before the mpfr_atan2 call. */
483 static void
atan2_bug_20071003(void)484 atan2_bug_20071003 (void)
485 {
486   mpfr_t a, x, y, z;
487 
488   mpfr_inits (a, x, y, z, (mpfr_ptr) 0);
489 
490   mpfr_set_underflow ();
491   mpfr_set_str_binary (y,
492     "-0.10100110110100110111010110111111100110100010001110110E2");
493   mpfr_set_str_binary (x,
494     "0.10100101010110010100010010111000110110011110001011110E3");
495   mpfr_set_str_binary (z,
496     "-0.11101111001101101100111011001101000010010111101110110E-1");
497   mpfr_atan2 (a, y, x, MPFR_RNDN);
498   if (! mpfr_equal_p (a, z))
499     {
500       printf ("mpfr_atan2 fails on:\n");
501       printf ("  y = ");
502       mpfr_dump (y);
503       printf ("  x = ");
504       mpfr_dump (x);
505       printf ("Expected ");
506       mpfr_dump (z);
507       printf ("Got      ");
508       mpfr_dump (a);
509       exit (1);
510     }
511 
512   mpfr_clears (a, x, y, z, (mpfr_ptr) 0);
513 }
514 
515 /* Bug found on 2009-04-29 by Christopher Creutzig.
516  * With r6179: atan.c:62: MPFR assertion failed: r > n
517  */
518 static void
atan2_different_prec(void)519 atan2_different_prec (void)
520 {
521   mpfr_t a, x, y;
522 
523   mpfr_init2 (a, 59);
524   mpfr_init2 (x, 59);
525   mpfr_init2 (y, 86);
526 
527   mpfr_set_ui (x, 1, MPFR_RNDN);
528   mpfr_set_ui (y, 1, MPFR_RNDN);
529   mpfr_nextbelow (y);
530   mpfr_atan2 (a, y, x, MPFR_RNDN);
531 
532   mpfr_clears (a, x, y, (mpfr_ptr) 0);
533 }
534 
535 static void
atan2_pow_of_2(void)536 atan2_pow_of_2 (void)
537 {
538   mpfr_t x, y, r, g;
539   int i;
540   int d[] = { 0, -1, 1 };
541   int ntests = numberof (d);
542 
543   mpfr_init2 (x, 53);
544   mpfr_init2 (y, 53);
545   mpfr_init2 (r, 53);
546   mpfr_init2 (g, 53);
547 
548   /* atan(42) */
549   mpfr_set_str_binary (g, "1100011000000011110011111001100110101000011010010011E-51");
550 
551   for (i = 0; i < ntests; ++i)
552     {
553       mpfr_set_ui (y, 42, MPFR_RNDN);
554       mpfr_mul_2si (y, y, d[i], MPFR_RNDN);
555       mpfr_set_ui_2exp (x, 1, d[i], MPFR_RNDN);
556       mpfr_atan2 (r, y, x, MPFR_RNDN);
557       if (mpfr_equal_p (r, g) == 0)
558         {
559           printf ("Error in mpfr_atan2 (5)\n");
560           printf ("Expected "); mpfr_dump (g);
561           printf ("Got      "); mpfr_dump (r);
562           exit (1);
563         }
564     }
565   mpfr_clear (x);
566   mpfr_clear (y);
567   mpfr_clear (r);
568   mpfr_clear (g);
569 }
570 
571 /* https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00008.html
572  * Incorrect flags (in debug mode on a 32-bit machine, assertion failure).
573  */
574 static void
reduced_expo_range(void)575 reduced_expo_range (void)
576 {
577   mpfr_exp_t emin, emax;
578   mpfr_t x, y, ex_y;
579   int inex, ex_inex;
580   unsigned int flags, ex_flags;
581 
582   emin = mpfr_get_emin ();
583   emax = mpfr_get_emax ();
584 
585   mpfr_inits2 (12, x, y, ex_y, (mpfr_ptr) 0);
586   mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN);
587 
588   set_emin (-5);
589   set_emax (-5);
590   mpfr_clear_flags ();
591   inex = mpfr_atan (y, x, MPFR_RNDN);
592   flags = __gmpfr_flags;
593   set_emin (emin);
594   set_emax (emax);
595 
596   mpfr_set_str (ex_y, "0.1e-5", 2, MPFR_RNDN);
597   ex_inex = 1;
598   ex_flags = MPFR_FLAGS_INEXACT;
599 
600   if (VSIGN (inex) != ex_inex || flags != ex_flags ||
601       ! mpfr_equal_p (y, ex_y))
602     {
603       printf ("Error in reduced_expo_range\non x = ");
604       mpfr_dump (x);
605       printf ("Expected y = ");
606       mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
607       printf ("\n         inex = %d, flags = %u\n", ex_inex, ex_flags);
608       printf ("Got      y = ");
609       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
610       printf ("\n         inex = %d, flags = %u\n", VSIGN (inex), flags);
611       exit (1);
612     }
613 
614   mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
615 }
616 
617 int
main(int argc,char * argv[])618 main (int argc, char *argv[])
619 {
620   tests_start_mpfr ();
621 
622   special_overflow ();
623   special ();
624   special_atan2 ();
625   smallvals_atan2 ();
626   atan2_bug_20071003 ();
627   atan2_different_prec ();
628   reduced_expo_range ();
629 
630   test_generic_atan  (MPFR_PREC_MIN, 200, 17);
631   test_generic_atan2 (MPFR_PREC_MIN, 200, 17);
632   test_generic_atan2_neg (MPFR_PREC_MIN, 200, 17);
633 
634   data_check ("data/atan", mpfr_atan, "mpfr_atan");
635   bad_cases (mpfr_atan, mpfr_tan, "mpfr_atan", 256, -40, 1, 4, 128, 800, 40);
636   atan2_pow_of_2 ();
637 
638   tests_end_mpfr ();
639   return 0;
640 }
641