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