sqrt.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package math
  5. //extern sqrt
  6. func libc_sqrt(float64) float64
  7. func Sqrt(x float64) float64 {
  8. return libc_sqrt(x)
  9. }
  10. // The original C code and the long comment below are
  11. // from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and
  12. // came with this notice. The go code is a simplified
  13. // version of the original C.
  14. //
  15. // ====================================================
  16. // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  17. //
  18. // Developed at SunPro, a Sun Microsystems, Inc. business.
  19. // Permission to use, copy, modify, and distribute this
  20. // software is freely granted, provided that this notice
  21. // is preserved.
  22. // ====================================================
  23. //
  24. // __ieee754_sqrt(x)
  25. // Return correctly rounded sqrt.
  26. // -----------------------------------------
  27. // | Use the hardware sqrt if you have one |
  28. // -----------------------------------------
  29. // Method:
  30. // Bit by bit method using integer arithmetic. (Slow, but portable)
  31. // 1. Normalization
  32. // Scale x to y in [1,4) with even powers of 2:
  33. // find an integer k such that 1 <= (y=x*2**(2k)) < 4, then
  34. // sqrt(x) = 2**k * sqrt(y)
  35. // 2. Bit by bit computation
  36. // Let q = sqrt(y) truncated to i bit after binary point (q = 1),
  37. // i 0
  38. // i+1 2
  39. // s = 2*q , and y = 2 * ( y - q ). (1)
  40. // i i i i
  41. //
  42. // To compute q from q , one checks whether
  43. // i+1 i
  44. //
  45. // -(i+1) 2
  46. // (q + 2 ) <= y. (2)
  47. // i
  48. // -(i+1)
  49. // If (2) is false, then q = q ; otherwise q = q + 2 .
  50. // i+1 i i+1 i
  51. //
  52. // With some algebraic manipulation, it is not difficult to see
  53. // that (2) is equivalent to
  54. // -(i+1)
  55. // s + 2 <= y (3)
  56. // i i
  57. //
  58. // The advantage of (3) is that s and y can be computed by
  59. // i i
  60. // the following recurrence formula:
  61. // if (3) is false
  62. //
  63. // s = s , y = y ; (4)
  64. // i+1 i i+1 i
  65. //
  66. // otherwise,
  67. // -i -(i+1)
  68. // s = s + 2 , y = y - s - 2 (5)
  69. // i+1 i i+1 i i
  70. //
  71. // One may easily use induction to prove (4) and (5).
  72. // Note. Since the left hand side of (3) contain only i+2 bits,
  73. // it does not necessary to do a full (53-bit) comparison
  74. // in (3).
  75. // 3. Final rounding
  76. // After generating the 53 bits result, we compute one more bit.
  77. // Together with the remainder, we can decide whether the
  78. // result is exact, bigger than 1/2ulp, or less than 1/2ulp
  79. // (it will never equal to 1/2ulp).
  80. // The rounding mode can be detected by checking whether
  81. // huge + tiny is equal to huge, and whether huge - tiny is
  82. // equal to huge for some floating point number "huge" and "tiny".
  83. //
  84. //
  85. // Notes: Rounding mode detection omitted. The constants "mask", "shift",
  86. // and "bias" are found in src/math/bits.go
  87. // Sqrt returns the square root of x.
  88. //
  89. // Special cases are:
  90. // Sqrt(+Inf) = +Inf
  91. // Sqrt(±0) = ±0
  92. // Sqrt(x < 0) = NaN
  93. // Sqrt(NaN) = NaN
  94. func sqrt(x float64) float64 {
  95. // special cases
  96. switch {
  97. case x == 0 || IsNaN(x) || IsInf(x, 1):
  98. return x
  99. case x < 0:
  100. return NaN()
  101. }
  102. ix := Float64bits(x)
  103. // normalize x
  104. exp := int((ix >> shift) & mask)
  105. if exp == 0 { // subnormal x
  106. for ix&1<<shift == 0 {
  107. ix <<= 1
  108. exp--
  109. }
  110. exp++
  111. }
  112. exp -= bias // unbias exponent
  113. ix &^= mask << shift
  114. ix |= 1 << shift
  115. if exp&1 == 1 { // odd exp, double x to make it even
  116. ix <<= 1
  117. }
  118. exp >>= 1 // exp = exp/2, exponent of square root
  119. // generate sqrt(x) bit by bit
  120. ix <<= 1
  121. var q, s uint64 // q = sqrt(x)
  122. r := uint64(1 << (shift + 1)) // r = moving bit from MSB to LSB
  123. for r != 0 {
  124. t := s + r
  125. if t <= ix {
  126. s = t + r
  127. ix -= t
  128. q += r
  129. }
  130. ix <<= 1
  131. r >>= 1
  132. }
  133. // final rounding
  134. if ix != 0 { // remainder, result not exact
  135. q += q & 1 // round according to extra bit
  136. }
  137. ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent
  138. return Float64frombits(ix)
  139. }
  140. func sqrtC(f float64, r *float64) {
  141. *r = sqrt(f)
  142. }