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