cbrtl.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* cbrtl.c
  2. *
  3. * Cube root, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, cbrtl();
  10. *
  11. * y = cbrtl( 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. * IEEE .125,8 80000 7.0e-20 2.2e-20
  33. * IEEE exp(+-707) 100000 7.0e-20 2.4e-20
  34. *
  35. */
  36. /*
  37. Cephes Math Library Release 2.2: January, 1991
  38. Copyright 1984, 1991 by Stephen L. Moshier
  39. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  40. */
  41. #include <math.h>
  42. static long double CBRT2 = 1.2599210498948731647672L;
  43. static long double CBRT4 = 1.5874010519681994747517L;
  44. static long double CBRT2I = 0.79370052598409973737585L;
  45. static long double CBRT4I = 0.62996052494743658238361L;
  46. #ifdef ANSIPROT
  47. extern long double frexpl ( long double, int * );
  48. extern long double ldexpl ( long double, int );
  49. extern int isnanl ( long double );
  50. #else
  51. long double frexpl(), ldexpl();
  52. extern int isnanl();
  53. #endif
  54. #ifdef INFINITIES
  55. extern long double INFINITYL;
  56. #endif
  57. long double cbrtl(x)
  58. long double x;
  59. {
  60. int e, rem, sign;
  61. long double z;
  62. #ifdef NANS
  63. if(isnanl(x))
  64. return(x);
  65. #endif
  66. #ifdef INFINITIES
  67. if( x == INFINITYL)
  68. return(x);
  69. if( x == -INFINITYL)
  70. return(x);
  71. #endif
  72. if( x == 0 )
  73. return( x );
  74. if( x > 0 )
  75. sign = 1;
  76. else
  77. {
  78. sign = -1;
  79. x = -x;
  80. }
  81. z = x;
  82. /* extract power of 2, leaving
  83. * mantissa between 0.5 and 1
  84. */
  85. x = frexpl( x, &e );
  86. /* Approximate cube root of number between .5 and 1,
  87. * peak relative error = 1.2e-6
  88. */
  89. x = (((( 1.3584464340920900529734e-1L * x
  90. - 6.3986917220457538402318e-1L) * x
  91. + 1.2875551670318751538055e0L) * x
  92. - 1.4897083391357284957891e0L) * x
  93. + 1.3304961236013647092521e0L) * x
  94. + 3.7568280825958912391243e-1L;
  95. /* exponent divided by 3 */
  96. if( e >= 0 )
  97. {
  98. rem = e;
  99. e /= 3;
  100. rem -= 3*e;
  101. if( rem == 1 )
  102. x *= CBRT2;
  103. else if( rem == 2 )
  104. x *= CBRT4;
  105. }
  106. else
  107. { /* argument less than 1 */
  108. e = -e;
  109. rem = e;
  110. e /= 3;
  111. rem -= 3*e;
  112. if( rem == 1 )
  113. x *= CBRT2I;
  114. else if( rem == 2 )
  115. x *= CBRT4I;
  116. e = -e;
  117. }
  118. /* multiply by power of 2 */
  119. x = ldexpl( x, e );
  120. /* Newton iteration */
  121. x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
  122. x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
  123. if( sign < 0 )
  124. x = -x;
  125. return(x);
  126. }