Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /* ef_atan2.c -- float version of e_atan2.c.
  2.  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  3.  */
  4.  
  5. /*
  6.  * ====================================================
  7.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  8.  *
  9.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software is freely granted, provided that this notice
  12.  * is preserved.
  13.  * ====================================================
  14.  *
  15.  */
  16.  
  17. #include "fdlibm.h"
  18.  
  19. #ifdef __STDC__
  20. static const float
  21. #else
  22. static float
  23. #endif
  24. tiny  = 1.0e-30,
  25. zero  = 0.0,
  26. pi_o_4  = 7.8539818525e-01, /* 0x3f490fdb */
  27. pi_o_2  = 1.5707963705e+00, /* 0x3fc90fdb */
  28. pi      = 3.1415927410e+00,  /* 0x40490fdb */
  29. pi_lo   = -8.7422776573e-08; /* 0xb3bbbd2e */
  30.  
  31. #ifdef __STDC__
  32.         float __ieee754_atan2f(float y, float x)
  33. #else
  34.         float __ieee754_atan2f(y,x)
  35.         float  y,x;
  36. #endif
  37. {  
  38.         float z;
  39.         __int32_t k,m,hx,hy,ix,iy;
  40.  
  41.         GET_FLOAT_WORD(hx,x);
  42.         ix = hx&0x7fffffff;
  43.         GET_FLOAT_WORD(hy,y);
  44.         iy = hy&0x7fffffff;
  45.         if(FLT_UWORD_IS_NAN(ix)||
  46.            FLT_UWORD_IS_NAN(iy))        /* x or y is NaN */
  47.            return x+y;
  48.         if(hx==0x3f800000) return atanf(y);   /* x=1.0 */
  49.         m = ((hy>>31)&1)|((hx>>30)&2);  /* 2*sign(x)+sign(y) */
  50.  
  51.     /* when y = 0 */
  52.         if(FLT_UWORD_IS_ZERO(iy)) {
  53.             switch(m) {
  54.                 case 0:
  55.                 case 1: return y;       /* atan(+-0,+anything)=+-0 */
  56.                 case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
  57.                 case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
  58.             }
  59.         }
  60.     /* when x = 0 */
  61.         if(FLT_UWORD_IS_ZERO(ix)) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
  62.            
  63.     /* when x is INF */
  64.         if(FLT_UWORD_IS_INFINITE(ix)) {
  65.             if(FLT_UWORD_IS_INFINITE(iy)) {
  66.                 switch(m) {
  67.                     case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
  68.                     case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
  69.                     case 2: return  (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
  70.                     case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
  71.                 }
  72.             } else {
  73.                 switch(m) {
  74.                     case 0: return  zero  ;     /* atan(+...,+INF) */
  75.                     case 1: return -zero  ;     /* atan(-...,+INF) */
  76.                     case 2: return  pi+tiny  ;  /* atan(+...,-INF) */
  77.                     case 3: return -pi-tiny  ;  /* atan(-...,-INF) */
  78.                 }
  79.             }
  80.         }
  81.     /* when y is INF */
  82.         if(FLT_UWORD_IS_INFINITE(iy)) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
  83.  
  84.     /* compute y/x */
  85.         k = (iy-ix)>>23;
  86.         if(k > 60) z=pi_o_2+(float)0.5*pi_lo;   /* |y/x| >  2**60 */
  87.         else if(hx<0&&k<-60) z=0.0;     /* |y|/x < -2**60 */
  88.         else z=atanf(fabsf(y/x));       /* safe to do y/x */
  89.         switch (m) {
  90.             case 0: return       z  ;   /* atan(+,+) */
  91.             case 1: {
  92.                       __uint32_t zh;
  93.                       GET_FLOAT_WORD(zh,z);
  94.                       SET_FLOAT_WORD(z,zh ^ 0x80000000);
  95.                     }
  96.                     return       z  ;   /* atan(-,+) */
  97.             case 2: return  pi-(z-pi_lo);/* atan(+,-) */
  98.             default: /* case 3 */
  99.                     return  (z-pi_lo)-pi;/* atan(-,-) */
  100.         }
  101. }
  102.