atan2f.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */
  2. /*
  3. * Conversion to float by Ian Lance Taylor, Cygnus Support, [email protected].
  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. #include "libm.h"
  16. static const float
  17. pi = 3.1415927410e+00, /* 0x40490fdb */
  18. pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
  19. float atan2f(float y, float x)
  20. {
  21. float z;
  22. uint32_t m,ix,iy;
  23. if (isnan(x) || isnan(y))
  24. return x+y;
  25. GET_FLOAT_WORD(ix, x);
  26. GET_FLOAT_WORD(iy, y);
  27. if (ix == 0x3f800000) /* x=1.0 */
  28. return atanf(y);
  29. m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */
  30. ix &= 0x7fffffff;
  31. iy &= 0x7fffffff;
  32. /* when y = 0 */
  33. if (iy == 0) {
  34. switch (m) {
  35. case 0:
  36. case 1: return y; /* atan(+-0,+anything)=+-0 */
  37. case 2: return pi; /* atan(+0,-anything) = pi */
  38. case 3: return -pi; /* atan(-0,-anything) =-pi */
  39. }
  40. }
  41. /* when x = 0 */
  42. if (ix == 0)
  43. return m&1 ? -pi/2 : pi/2;
  44. /* when x is INF */
  45. if (ix == 0x7f800000) {
  46. if (iy == 0x7f800000) {
  47. switch (m) {
  48. case 0: return pi/4; /* atan(+INF,+INF) */
  49. case 1: return -pi/4; /* atan(-INF,+INF) */
  50. case 2: return 3*pi/4; /*atan(+INF,-INF)*/
  51. case 3: return -3*pi/4; /*atan(-INF,-INF)*/
  52. }
  53. } else {
  54. switch (m) {
  55. case 0: return 0.0f; /* atan(+...,+INF) */
  56. case 1: return -0.0f; /* atan(-...,+INF) */
  57. case 2: return pi; /* atan(+...,-INF) */
  58. case 3: return -pi; /* atan(-...,-INF) */
  59. }
  60. }
  61. }
  62. /* |y/x| > 0x1p26 */
  63. if (ix+(26<<23) < iy || iy == 0x7f800000)
  64. return m&1 ? -pi/2 : pi/2;
  65. /* z = atan(|y/x|) with correct underflow */
  66. if ((m&2) && iy+(26<<23) < ix) /*|y/x| < 0x1p-26, x < 0 */
  67. z = 0.0;
  68. else
  69. z = atanf(fabsf(y/x));
  70. switch (m) {
  71. case 0: return z; /* atan(+,+) */
  72. case 1: return -z; /* atan(-,+) */
  73. case 2: return pi - (z-pi_lo); /* atan(+,-) */
  74. default: /* case 3 */
  75. return (z-pi_lo) - pi; /* atan(-,-) */
  76. }
  77. }