cbrtl.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtl.c */
  2. /*-
  3. * ====================================================
  4. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5. * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.
  6. *
  7. * Developed at SunPro, a Sun Microsystems, Inc. business.
  8. * Permission to use, copy, modify, and distribute this
  9. * software is freely granted, provided that this notice
  10. * is preserved.
  11. * ====================================================
  12. *
  13. * The argument reduction and testing for exceptional cases was
  14. * written by Steven G. Kargl with input from Bruce D. Evans
  15. * and David A. Schultz.
  16. */
  17. #include "libm.h"
  18. #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
  19. long double cbrtl(long double x)
  20. {
  21. return cbrt(x);
  22. }
  23. #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
  24. static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */
  25. long double cbrtl(long double x)
  26. {
  27. union ldshape u = {x}, v;
  28. union {float f; uint32_t i;} uft;
  29. long double r, s, t, w;
  30. double_t dr, dt, dx;
  31. float_t ft;
  32. int e = u.i.se & 0x7fff;
  33. int sign = u.i.se & 0x8000;
  34. /*
  35. * If x = +-Inf, then cbrt(x) = +-Inf.
  36. * If x = NaN, then cbrt(x) = NaN.
  37. */
  38. if (e == 0x7fff)
  39. return x + x;
  40. if (e == 0) {
  41. /* Adjust subnormal numbers. */
  42. u.f *= 0x1p120;
  43. e = u.i.se & 0x7fff;
  44. /* If x = +-0, then cbrt(x) = +-0. */
  45. if (e == 0)
  46. return x;
  47. e -= 120;
  48. }
  49. e -= 0x3fff;
  50. u.i.se = 0x3fff;
  51. x = u.f;
  52. switch (e % 3) {
  53. case 1:
  54. case -2:
  55. x *= 2;
  56. e--;
  57. break;
  58. case 2:
  59. case -1:
  60. x *= 4;
  61. e -= 2;
  62. break;
  63. }
  64. v.f = 1.0;
  65. v.i.se = sign | (0x3fff + e/3);
  66. /*
  67. * The following is the guts of s_cbrtf, with the handling of
  68. * special values removed and extra care for accuracy not taken,
  69. * but with most of the extra accuracy not discarded.
  70. */
  71. /* ~5-bit estimate: */
  72. uft.f = x;
  73. uft.i = (uft.i & 0x7fffffff)/3 + B1;
  74. ft = uft.f;
  75. /* ~16-bit estimate: */
  76. dx = x;
  77. dt = ft;
  78. dr = dt * dt * dt;
  79. dt = dt * (dx + dx + dr) / (dx + dr + dr);
  80. /* ~47-bit estimate: */
  81. dr = dt * dt * dt;
  82. dt = dt * (dx + dx + dr) / (dx + dr + dr);
  83. #if LDBL_MANT_DIG == 64
  84. /*
  85. * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8).
  86. * Round it away from zero to 32 bits (32 so that t*t is exact, and
  87. * away from zero for technical reasons).
  88. */
  89. t = dt + (0x1.0p32L + 0x1.0p-31L) - 0x1.0p32;
  90. #elif LDBL_MANT_DIG == 113
  91. /*
  92. * Round dt away from zero to 47 bits. Since we don't trust the 47,
  93. * add 2 47-bit ulps instead of 1 to round up. Rounding is slow and
  94. * might be avoidable in this case, since on most machines dt will
  95. * have been evaluated in 53-bit precision and the technical reasons
  96. * for rounding up might not apply to either case in cbrtl() since
  97. * dt is much more accurate than needed.
  98. */
  99. t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60;
  100. #endif
  101. /*
  102. * Final step Newton iteration to 64 or 113 bits with
  103. * error < 0.667 ulps
  104. */
  105. s = t*t; /* t*t is exact */
  106. r = x/s; /* error <= 0.5 ulps; |r| < |t| */
  107. w = t+t; /* t+t is exact */
  108. r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
  109. t = t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */
  110. t *= v.f;
  111. return t;
  112. }
  113. #endif