sqrtl.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* sqrtl.c
  2. *
  3. * Square root, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, sqrtl();
  10. *
  11. * y = sqrtl( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns the square root of x.
  18. *
  19. * Range reduction involves isolating the power of two of the
  20. * argument and using a polynomial approximation to obtain
  21. * a rough value for the square root. Then Heron's iteration
  22. * is used three times to converge to an accurate value.
  23. *
  24. * Note, some arithmetic coprocessors such as the 8087 and
  25. * 68881 produce correctly rounded square roots, which this
  26. * routine will not.
  27. *
  28. * ACCURACY:
  29. *
  30. *
  31. * Relative error:
  32. * arithmetic domain # trials peak rms
  33. * IEEE 0,10 30000 8.1e-20 3.1e-20
  34. *
  35. *
  36. * ERROR MESSAGES:
  37. *
  38. * message condition value returned
  39. * sqrt domain x < 0 0.0
  40. *
  41. */
  42. /*
  43. Cephes Math Library Release 2.2: December, 1990
  44. Copyright 1984, 1990 by Stephen L. Moshier
  45. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  46. */
  47. #include <math.h>
  48. #define SQRT2 1.4142135623730950488017E0L
  49. #ifdef ANSIPROT
  50. extern long double frexpl ( long double, int * );
  51. extern long double ldexpl ( long double, int );
  52. #else
  53. long double frexpl(), ldexpl();
  54. #endif
  55. long double sqrtl(x)
  56. long double x;
  57. {
  58. int e;
  59. long double z, w;
  60. #ifndef UNK
  61. short *q;
  62. #endif
  63. if( x <= 0.0 )
  64. {
  65. if( x < 0.0 )
  66. mtherr( "sqrtl", DOMAIN );
  67. return( 0.0 );
  68. }
  69. w = x;
  70. /* separate exponent and significand */
  71. #ifdef UNK
  72. z = frexpl( x, &e );
  73. #endif
  74. /* Note, frexp and ldexp are used in order to
  75. * handle denormal numbers properly.
  76. */
  77. #ifdef IBMPC
  78. z = frexpl( x, &e );
  79. q = (short *)&x; /* point to the exponent word */
  80. q += 4;
  81. /*
  82. e = ((*q >> 4) & 0x0fff) - 0x3fe;
  83. *q &= 0x000f;
  84. *q |= 0x3fe0;
  85. z = x;
  86. */
  87. #endif
  88. #ifdef MIEEE
  89. z = frexpl( x, &e );
  90. q = (short *)&x;
  91. /*
  92. e = ((*q >> 4) & 0x0fff) - 0x3fe;
  93. *q &= 0x000f;
  94. *q |= 0x3fe0;
  95. z = x;
  96. */
  97. #endif
  98. /* approximate square root of number between 0.5 and 1
  99. * relative error of linear approximation = 7.47e-3
  100. */
  101. /*
  102. x = 0.4173075996388649989089L + 0.59016206709064458299663L * z;
  103. */
  104. /* quadratic approximation, relative error 6.45e-4 */
  105. x = ( -0.20440583154734771959904L * z
  106. + 0.89019407351052789754347L) * z
  107. + 0.31356706742295303132394L;
  108. /* adjust for odd powers of 2 */
  109. if( (e & 1) != 0 )
  110. x *= SQRT2;
  111. /* re-insert exponent */
  112. #ifdef UNK
  113. x = ldexpl( x, (e >> 1) );
  114. #endif
  115. #ifdef IBMPC
  116. x = ldexpl( x, (e >> 1) );
  117. /*
  118. *q += ((e >>1) & 0x7ff) << 4;
  119. *q &= 077777;
  120. */
  121. #endif
  122. #ifdef MIEEE
  123. x = ldexpl( x, (e >> 1) );
  124. /*
  125. *q += ((e >>1) & 0x7ff) << 4;
  126. *q &= 077777;
  127. */
  128. #endif
  129. /* Newton iterations: */
  130. #ifdef UNK
  131. x += w/x;
  132. x = ldexpl( x, -1 ); /* divide by 2 */
  133. x += w/x;
  134. x = ldexpl( x, -1 );
  135. x += w/x;
  136. x = ldexpl( x, -1 );
  137. #endif
  138. /* Note, assume the square root cannot be denormal,
  139. * so it is safe to use integer exponent operations here.
  140. */
  141. #ifdef IBMPC
  142. x += w/x;
  143. *q -= 1;
  144. x += w/x;
  145. *q -= 1;
  146. x += w/x;
  147. *q -= 1;
  148. #endif
  149. #ifdef MIEEE
  150. x += w/x;
  151. *q -= 1;
  152. x += w/x;
  153. *q -= 1;
  154. x += w/x;
  155. *q -= 1;
  156. #endif
  157. return(x);
  158. }