Print this page
11175 libm should use signbit() correctly
11188 c99 math macros should return strictly backward compatible values


  56  * shown.
  57  */
  58 
  59 #pragma weak __atan2l = atan2l
  60 
  61 #include "libm.h"
  62 #include "longdouble.h"
  63 
  64 static const long double
  65         zero    =  0.0L,
  66         tiny    =  1.0e-40L,
  67         one     =  1.0L,
  68         half    =  0.5L,
  69         PI3o4   =  2.356194490192344928846982537459627163148L,
  70         PIo4    =  0.785398163397448309615660845819875721049L,
  71         PIo2    =  1.570796326794896619231321691639751442099L,
  72         PI      =  3.141592653589793238462643383279502884197L,
  73         PI_lo   =  8.671810130123781024797044026043351968762e-35L;
  74 
  75 long double
  76 atan2l(long double y, long double x) {

  77         long double t, z;
  78         int k, m, signy, signx;
  79 
  80         if (x != x || y != y)
  81                 return (x + y); /* return NaN if x or y is NAN */
  82         signy = signbitl(y);
  83         signx = signbitl(x);
  84         if (x == one)
  85                 return (atanl(y));
  86         m = signy + signx + signx;

  87 
  88         /* when y = 0 */
  89         if (y == zero)
  90                 switch (m) {
  91                 case 0:
  92                         return (y);     /* atan(+0,+anything) */
  93                 case 1:
  94                         return (y);     /* atan(-0,+anything) */
  95                 case 2:
  96                         return (PI + tiny);     /* atan(+0,-anything) */
  97                 case 3:
  98                         return (-PI - tiny);    /* atan(-0,-anything) */
  99                 }
 100 
 101         /* when x = 0 */
 102         if (x == zero)
 103                 return (signy == 1 ? -PIo2 - tiny : PIo2 + tiny);
 104 
 105         /* when x is INF */
 106         if (!finitel(x)) {
 107                 if (!finitel(y)) {
 108                         switch (m) {
 109                         case 0:
 110                                 return (PIo4 + tiny);   /* atan(+INF,+INF) */
 111                         case 1:
 112                                 return (-PIo4 - tiny);  /* atan(-INF,+INF) */
 113                         case 2:
 114                                 return (PI3o4 + tiny);  /* atan(+INF,-INF) */
 115                         case 3:
 116                                 return (-PI3o4 - tiny); /* atan(-INF,-INF) */
 117                         }
 118                 } else {
 119                         switch (m) {
 120                         case 0:
 121                                 return (zero);  /* atan(+...,+INF) */
 122                         case 1:
 123                                 return (-zero); /* atan(-...,+INF) */
 124                         case 2:
 125                                 return (PI + tiny);     /* atan(+...,-INF) */
 126                         case 3:
 127                                 return (-PI - tiny);    /* atan(-...,-INF) */
 128                         }
 129                 }
 130         }
 131         /* when y is INF */
 132         if (!finitel(y))
 133                 return (signy == 1 ? -PIo2 - tiny : PIo2 + tiny);
 134 
 135         /* compute y/x */
 136         x = fabsl(x);
 137         y = fabsl(y);
 138         t = PI_lo;
 139         k = (ilogbl(y) - ilogbl(x));
 140 
 141         if (k > 120)
 142                 z = PIo2 + half * t;
 143         else if (m > 1 && k < -120)
 144                 z = zero;
 145         else
 146                 z = atanl(y / x);
 147 
 148         switch (m) {
 149         case 0:
 150                 return (z);     /* atan(+,+) */
 151         case 1:
 152                 return (-z);    /* atan(-,+) */
 153         case 2:
 154                 return (PI - (z - t));  /* atan(+,-) */
 155         case 3:
 156                 return ((z - t) - PI);  /* atan(-,-) */
 157         }
 158         /* NOTREACHED */
 159     return 0.0L;
 160 }


  56  * shown.
  57  */
  58 
  59 #pragma weak __atan2l = atan2l
  60 
  61 #include "libm.h"
  62 #include "longdouble.h"
  63 
  64 static const long double
  65         zero    =  0.0L,
  66         tiny    =  1.0e-40L,
  67         one     =  1.0L,
  68         half    =  0.5L,
  69         PI3o4   =  2.356194490192344928846982537459627163148L,
  70         PIo4    =  0.785398163397448309615660845819875721049L,
  71         PIo2    =  1.570796326794896619231321691639751442099L,
  72         PI      =  3.141592653589793238462643383279502884197L,
  73         PI_lo   =  8.671810130123781024797044026043351968762e-35L;
  74 
  75 long double
  76 atan2l(long double y, long double x)
  77 {
  78         long double t, z;
  79         int k, m, signy, signx;
  80 
  81         if (x != x || y != y)
  82                 return (x + y); /* return NaN if x or y is NAN */
  83         signy = signbitl(y);
  84         signx = signbitl(x);
  85         if (x == one)
  86                 return (atanl(y));
  87         /* Ensure sign indicators are boolean */
  88         m = (signy != 0) + (signx != 0) + (signx != 0);
  89 
  90         /* when y = 0 */
  91         if (y == zero)
  92                 switch (m) {
  93                 case 0:
  94                         return (y);     /* atan(+0,+anything) */
  95                 case 1:
  96                         return (y);     /* atan(-0,+anything) */
  97                 case 2:
  98                         return (PI + tiny);     /* atan(+0,-anything) */
  99                 case 3:
 100                         return (-PI - tiny);    /* atan(-0,-anything) */
 101                 }
 102 
 103         /* when x = 0 */
 104         if (x == zero)
 105                 return (signy != 0 ? -PIo2 - tiny : PIo2 + tiny);
 106 
 107         /* when x is INF */
 108         if (!finitel(x)) {
 109                 if (!finitel(y)) {
 110                         switch (m) {
 111                         case 0:
 112                                 return (PIo4 + tiny);   /* atan(+INF,+INF) */
 113                         case 1:
 114                                 return (-PIo4 - tiny);  /* atan(-INF,+INF) */
 115                         case 2:
 116                                 return (PI3o4 + tiny);  /* atan(+INF,-INF) */
 117                         case 3:
 118                                 return (-PI3o4 - tiny); /* atan(-INF,-INF) */
 119                         }
 120                 } else {
 121                         switch (m) {
 122                         case 0:
 123                                 return (zero);  /* atan(+...,+INF) */
 124                         case 1:
 125                                 return (-zero); /* atan(-...,+INF) */
 126                         case 2:
 127                                 return (PI + tiny);     /* atan(+...,-INF) */
 128                         case 3:
 129                                 return (-PI - tiny);    /* atan(-...,-INF) */
 130                         }
 131                 }
 132         }
 133         /* when y is INF */
 134         if (!finitel(y))
 135                 return (signy != 0 ? -PIo2 - tiny : PIo2 + tiny);
 136 
 137         /* compute y/x */
 138         x = fabsl(x);
 139         y = fabsl(y);
 140         t = PI_lo;
 141         k = (ilogbl(y) - ilogbl(x));
 142 
 143         if (k > 120)
 144                 z = PIo2 + half * t;
 145         else if (m > 1 && k < -120)
 146                 z = zero;
 147         else
 148                 z = atanl(y / x);
 149 
 150         switch (m) {
 151         case 0:
 152                 return (z);     /* atan(+,+) */
 153         case 1:
 154                 return (-z);    /* atan(-,+) */
 155         case 2:
 156                 return (PI - (z - t));  /* atan(+,-) */
 157         case 3:
 158                 return ((z - t) - PI);  /* atan(-,-) */
 159         }
 160         /* NOTREACHED */
 161         return (0.0L);
 162 }