(root)/
mpfr-4.2.1/
tests/
tatan.c
       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
      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
     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
     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
     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
     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
     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
     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
     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
     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  }