Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 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 | |
Rob Pike | 4331293 | 2008-06-27 17:06:23 -0700 | [diff] [blame] | 5 | package math |
Ken Thompson | 2181098 | 2008-03-28 13:56:47 -0700 | [diff] [blame] | 6 | |
Russ Cox | dd8dc6f | 2011-12-13 15:20:12 -0500 | [diff] [blame] | 7 | // The original C code and the long comment below are |
| 8 | // from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and |
| 9 | // came with this notice. The go code is a simplified |
| 10 | // version of the original C. |
| 11 | // |
| 12 | // ==================================================== |
| 13 | // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
| 14 | // |
| 15 | // Developed at SunPro, a Sun Microsystems, Inc. business. |
| 16 | // Permission to use, copy, modify, and distribute this |
| 17 | // software is freely granted, provided that this notice |
| 18 | // is preserved. |
| 19 | // ==================================================== |
| 20 | // |
| 21 | // __ieee754_sqrt(x) |
| 22 | // Return correctly rounded sqrt. |
| 23 | // ----------------------------------------- |
| 24 | // | Use the hardware sqrt if you have one | |
| 25 | // ----------------------------------------- |
| 26 | // Method: |
| 27 | // Bit by bit method using integer arithmetic. (Slow, but portable) |
| 28 | // 1. Normalization |
| 29 | // Scale x to y in [1,4) with even powers of 2: |
| 30 | // find an integer k such that 1 <= (y=x*2**(2k)) < 4, then |
| 31 | // sqrt(x) = 2**k * sqrt(y) |
| 32 | // 2. Bit by bit computation |
| 33 | // Let q = sqrt(y) truncated to i bit after binary point (q = 1), |
| 34 | // i 0 |
| 35 | // i+1 2 |
| 36 | // s = 2*q , and y = 2 * ( y - q ). (1) |
| 37 | // i i i i |
| 38 | // |
| 39 | // To compute q from q , one checks whether |
| 40 | // i+1 i |
| 41 | // |
| 42 | // -(i+1) 2 |
| 43 | // (q + 2 ) <= y. (2) |
| 44 | // i |
| 45 | // -(i+1) |
| 46 | // If (2) is false, then q = q ; otherwise q = q + 2 . |
| 47 | // i+1 i i+1 i |
| 48 | // |
| 49 | // With some algebraic manipulation, it is not difficult to see |
| 50 | // that (2) is equivalent to |
| 51 | // -(i+1) |
| 52 | // s + 2 <= y (3) |
| 53 | // i i |
| 54 | // |
| 55 | // The advantage of (3) is that s and y can be computed by |
| 56 | // i i |
| 57 | // the following recurrence formula: |
| 58 | // if (3) is false |
| 59 | // |
| 60 | // s = s , y = y ; (4) |
| 61 | // i+1 i i+1 i |
| 62 | // |
| 63 | // otherwise, |
| 64 | // -i -(i+1) |
| 65 | // s = s + 2 , y = y - s - 2 (5) |
| 66 | // i+1 i i+1 i i |
| 67 | // |
| 68 | // One may easily use induction to prove (4) and (5). |
| 69 | // Note. Since the left hand side of (3) contain only i+2 bits, |
| 70 | // it does not necessary to do a full (53-bit) comparison |
| 71 | // in (3). |
| 72 | // 3. Final rounding |
| 73 | // After generating the 53 bits result, we compute one more bit. |
| 74 | // Together with the remainder, we can decide whether the |
| 75 | // result is exact, bigger than 1/2ulp, or less than 1/2ulp |
| 76 | // (it will never equal to 1/2ulp). |
| 77 | // The rounding mode can be detected by checking whether |
| 78 | // huge + tiny is equal to huge, and whether huge - tiny is |
| 79 | // equal to huge for some floating point number "huge" and "tiny". |
| 80 | // |
| 81 | // |
| 82 | // Notes: Rounding mode detection omitted. The constants "mask", "shift", |
Russ Cox | 220a6de | 2014-09-08 00:06:45 -0400 | [diff] [blame] | 83 | // and "bias" are found in src/math/bits.go |
Russ Cox | dd8dc6f | 2011-12-13 15:20:12 -0500 | [diff] [blame] | 84 | |
| 85 | // Sqrt returns the square root of x. |
| 86 | // |
| 87 | // Special cases are: |
| 88 | // Sqrt(+Inf) = +Inf |
| 89 | // Sqrt(±0) = ±0 |
| 90 | // Sqrt(x < 0) = NaN |
| 91 | // Sqrt(NaN) = NaN |
Oling Cat | 79ae1ad | 2013-03-22 14:54:20 +1100 | [diff] [blame] | 92 | func Sqrt(x float64) float64 |
| 93 | |
Russ Cox | dd8dc6f | 2011-12-13 15:20:12 -0500 | [diff] [blame] | 94 | func sqrt(x float64) float64 { |
| 95 | // special cases |
Russ Cox | dd8dc6f | 2011-12-13 15:20:12 -0500 | [diff] [blame] | 96 | switch { |
Luuk van Dijk | 8dd3de4 | 2012-02-01 16:08:31 +0100 | [diff] [blame] | 97 | case x == 0 || IsNaN(x) || IsInf(x, 1): |
Russ Cox | dd8dc6f | 2011-12-13 15:20:12 -0500 | [diff] [blame] | 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 | |
| 141 | func sqrtC(f float64, r *float64) { |
| 142 | *r = sqrt(f) |
| 143 | } |