asinfacosf.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*****************************************************************************/
  2. /*****************************************************************************/
  3. // asinf from musl-0.9.15
  4. /*****************************************************************************/
  5. /*****************************************************************************/
  6. /* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
  7. /*
  8. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  9. */
  10. /*
  11. * ====================================================
  12. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  13. *
  14. * Developed at SunPro, a Sun Microsystems, Inc. business.
  15. * Permission to use, copy, modify, and distribute this
  16. * software is freely granted, provided that this notice
  17. * is preserved.
  18. * ====================================================
  19. */
  20. #include "libm.h"
  21. // dpgeorge: pio2 was double in original implementation of asinf
  22. static const float
  23. pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
  24. pio2_lo = 7.5497894159e-08; /* 0x33a22168 */
  25. static const float
  26. /* coefficients for R(x^2) */
  27. pS0 = 1.6666586697e-01,
  28. pS1 = -4.2743422091e-02,
  29. pS2 = -8.6563630030e-03,
  30. qS1 = -7.0662963390e-01;
  31. static float R(float z)
  32. {
  33. float_t p, q;
  34. p = z*(pS0+z*(pS1+z*pS2));
  35. q = 1.0f+z*qS1;
  36. return p/q;
  37. }
  38. float asinf(float x)
  39. {
  40. // dpgeorge: s was double in original implementation
  41. float s,z;
  42. uint32_t hx,ix;
  43. GET_FLOAT_WORD(hx, x);
  44. ix = hx & 0x7fffffff;
  45. if (ix >= 0x3f800000) { /* |x| >= 1 */
  46. if (ix == 0x3f800000) /* |x| == 1 */
  47. return x*pio2_hi + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */
  48. return 0/(x-x); /* asin(|x|>1) is NaN */
  49. }
  50. if (ix < 0x3f000000) { /* |x| < 0.5 */
  51. /* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
  52. if (ix < 0x39800000 && ix >= 0x00800000)
  53. return x;
  54. return x + x*R(x*x);
  55. }
  56. /* 1 > |x| >= 0.5 */
  57. z = (1 - fabsf(x))*0.5f;
  58. s = sqrtf(z);
  59. x = pio2_hi - (2*(s+s*R(z)) - pio2_lo); // dpgeorge: use pio2_hi and pio2_lo
  60. if (hx >> 31)
  61. return -x;
  62. return x;
  63. }
  64. /*****************************************************************************/
  65. /*****************************************************************************/
  66. // acosf from musl-0.9.15
  67. /*****************************************************************************/
  68. /*****************************************************************************/
  69. /* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
  70. /*
  71. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  72. */
  73. /*
  74. * ====================================================
  75. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  76. *
  77. * Developed at SunPro, a Sun Microsystems, Inc. business.
  78. * Permission to use, copy, modify, and distribute this
  79. * software is freely granted, provided that this notice
  80. * is preserved.
  81. * ====================================================
  82. */
  83. float acosf(float x)
  84. {
  85. float z,w,s,c,df;
  86. uint32_t hx,ix;
  87. GET_FLOAT_WORD(hx, x);
  88. ix = hx & 0x7fffffff;
  89. /* |x| >= 1 or nan */
  90. if (ix >= 0x3f800000) {
  91. if (ix == 0x3f800000) {
  92. if (hx >> 31)
  93. return 2*pio2_hi + 0x1p-120f;
  94. return 0;
  95. }
  96. return 0/(x-x);
  97. }
  98. /* |x| < 0.5 */
  99. if (ix < 0x3f000000) {
  100. if (ix <= 0x32800000) /* |x| < 2**-26 */
  101. return pio2_hi + 0x1p-120f;
  102. return pio2_hi - (x - (pio2_lo-x*R(x*x)));
  103. }
  104. /* x < -0.5 */
  105. if (hx >> 31) {
  106. z = (1+x)*0.5f;
  107. s = sqrtf(z);
  108. w = R(z)*s-pio2_lo;
  109. return 2*(pio2_hi - (s+w));
  110. }
  111. /* x > 0.5 */
  112. z = (1-x)*0.5f;
  113. s = sqrtf(z);
  114. GET_FLOAT_WORD(hx,s);
  115. SET_FLOAT_WORD(df,hx&0xfffff000);
  116. c = (z-df*df)/(s+df);
  117. w = R(z)*s+c;
  118. return 2*(df+w);
  119. }