asin.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. * Author: Ceriel J.H. Jacobs
  6. */
  7. /* $Id$ */
  8. #include <math.h>
  9. #include <errno.h>
  10. #include "localmath.h"
  11. static double
  12. asin_acos(double x, int cosfl)
  13. {
  14. int negative = x < 0;
  15. int i;
  16. double g;
  17. static double p[] = {
  18. -0.27368494524164255994e+2,
  19. 0.57208227877891731407e+2,
  20. -0.39688862997540877339e+2,
  21. 0.10152522233806463645e+2,
  22. -0.69674573447350646411e+0
  23. };
  24. static double q[] = {
  25. -0.16421096714498560795e+3,
  26. 0.41714430248260412556e+3,
  27. -0.38186303361750149284e+3,
  28. 0.15095270841030604719e+3,
  29. -0.23823859153670238830e+2,
  30. 1.0
  31. };
  32. if (__IsNan(x)) {
  33. errno = EDOM;
  34. return x;
  35. }
  36. if (negative) {
  37. x = -x;
  38. }
  39. if (x > 0.5) {
  40. i = 1;
  41. if (x > 1) {
  42. errno = EDOM;
  43. return 0;
  44. }
  45. g = 0.5 - 0.5 * x;
  46. x = - sqrt(g);
  47. x += x;
  48. }
  49. else {
  50. /* ??? avoid underflow ??? */
  51. i = 0;
  52. g = x * x;
  53. }
  54. x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
  55. if (cosfl) {
  56. if (! negative) x = -x;
  57. }
  58. if ((cosfl == 0) == (i == 1)) {
  59. x = (x + M_PI_4) + M_PI_4;
  60. }
  61. else if (cosfl && negative && i == 1) {
  62. x = (x + M_PI_2) + M_PI_2;
  63. }
  64. if (! cosfl && negative) x = -x;
  65. return x;
  66. }
  67. double
  68. asin(double x)
  69. {
  70. return asin_acos(x, 0);
  71. }
  72. double
  73. acos(double x)
  74. {
  75. return asin_acos(x, 1);
  76. }