cbrt.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* cbrt.c
  2. *
  3. * Cube root
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, cbrt();
  10. *
  11. * y = cbrt( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns the cube root of the argument, which may be negative.
  18. *
  19. * Range reduction involves determining the power of 2 of
  20. * the argument. A polynomial of degree 2 applied to the
  21. * mantissa, and multiplication by the cube root of 1, 2, or 4
  22. * approximates the root to within about 0.1%. Then Newton's
  23. * iteration is used three times to converge to an accurate
  24. * result.
  25. *
  26. *
  27. *
  28. * ACCURACY:
  29. *
  30. * Relative error:
  31. * arithmetic domain # trials peak rms
  32. * DEC -10,10 200000 1.8e-17 6.2e-18
  33. * IEEE 0,1e308 30000 1.5e-16 5.0e-17
  34. *
  35. */
  36. /* cbrt.c */
  37. /*
  38. Cephes Math Library Release 2.8: June, 2000
  39. Copyright 1984, 1991, 2000 by Stephen L. Moshier
  40. */
  41. #include "mconf.h"
  42. static double CBRT2 = 1.2599210498948731647672;
  43. static double CBRT4 = 1.5874010519681994747517;
  44. static double CBRT2I = 0.79370052598409973737585;
  45. static double CBRT4I = 0.62996052494743658238361;
  46. #ifdef ANSIPROT
  47. extern double frexp(double, int *);
  48. extern double ldexp(double, int);
  49. extern int isnan(double);
  50. extern int isfinite(double);
  51. #else
  52. double frexp(), ldexp();
  53. int isnan(), isfinite();
  54. #endif
  55. double cbrt(x) double x;
  56. {
  57. int e, rem, sign;
  58. double z;
  59. #ifdef NANS
  60. if (isnan(x))
  61. return x;
  62. #endif
  63. #ifdef INFINITIES
  64. if (!isfinite(x))
  65. return x;
  66. #endif
  67. if (x == 0)
  68. return (x);
  69. if (x > 0)
  70. sign = 1;
  71. else {
  72. sign = -1;
  73. x = -x;
  74. }
  75. z = x;
  76. /* extract power of 2, leaving
  77. * mantissa between 0.5 and 1
  78. */
  79. x = frexp(x, &e);
  80. /* Approximate cube root of number between .5 and 1,
  81. * peak relative error = 9.2e-6
  82. */
  83. x = (((-1.3466110473359520655053e-1 * x + 5.4664601366395524503440e-1) * x -
  84. 9.5438224771509446525043e-1) *
  85. x +
  86. 1.1399983354717293273738e0) *
  87. x +
  88. 4.0238979564544752126924e-1;
  89. /* exponent divided by 3 */
  90. if (e >= 0) {
  91. rem = e;
  92. e /= 3;
  93. rem -= 3 * e;
  94. if (rem == 1)
  95. x *= CBRT2;
  96. else if (rem == 2)
  97. x *= CBRT4;
  98. }
  99. /* argument less than 1 */
  100. else {
  101. e = -e;
  102. rem = e;
  103. e /= 3;
  104. rem -= 3 * e;
  105. if (rem == 1)
  106. x *= CBRT2I;
  107. else if (rem == 2)
  108. x *= CBRT4I;
  109. e = -e;
  110. }
  111. /* multiply by power of 2 */
  112. x = ldexp(x, e);
  113. /* Newton iteration */
  114. x -= (x - (z / (x * x))) * 0.33333333333333333333;
  115. #ifdef DEC
  116. x -= (x - (z / (x * x))) / 3.0;
  117. #else
  118. x -= (x - (z / (x * x))) * 0.33333333333333333333;
  119. #endif
  120. if (sign < 0)
  121. x = -x;
  122. return (x);
  123. }