...
Source file src/pkg/math/pow.go
1
2
3
4
5 package math
6
7 func isOddInt(x float64) bool {
8 xi, xf := Modf(x)
9 return xf == 0 && int64(xi)&1 == 1
10 }
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 func Pow(x, y float64) float64
39
40 func pow(x, y float64) float64 {
41 switch {
42 case y == 0 || x == 1:
43 return 1
44 case y == 1:
45 return x
46 case IsNaN(x) || IsNaN(y):
47 return NaN()
48 case x == 0:
49 switch {
50 case y < 0:
51 if isOddInt(y) {
52 return Copysign(Inf(1), x)
53 }
54 return Inf(1)
55 case y > 0:
56 if isOddInt(y) {
57 return x
58 }
59 return 0
60 }
61 case IsInf(y, 0):
62 switch {
63 case x == -1:
64 return 1
65 case (Abs(x) < 1) == IsInf(y, 1):
66 return 0
67 default:
68 return Inf(1)
69 }
70 case IsInf(x, 0):
71 if IsInf(x, -1) {
72 return Pow(1/x, -y)
73 }
74 switch {
75 case y < 0:
76 return 0
77 case y > 0:
78 return Inf(1)
79 }
80 case y == 0.5:
81 return Sqrt(x)
82 case y == -0.5:
83 return 1 / Sqrt(x)
84 }
85
86 yi, yf := Modf(Abs(y))
87 if yf != 0 && x < 0 {
88 return NaN()
89 }
90 if yi >= 1<<63 {
91
92
93 switch {
94 case x == -1:
95 return 1
96 case (Abs(x) < 1) == (y > 0):
97 return 0
98 default:
99 return Inf(1)
100 }
101 }
102
103
104 a1 := 1.0
105 ae := 0
106
107
108 if yf != 0 {
109 if yf > 0.5 {
110 yf--
111 yi++
112 }
113 a1 = Exp(yf * Log(x))
114 }
115
116
117
118
119
120 x1, xe := Frexp(x)
121 for i := int64(yi); i != 0; i >>= 1 {
122 if xe < -1<<12 || 1<<12 < xe {
123
124
125
126
127
128 ae += xe
129 break
130 }
131 if i&1 == 1 {
132 a1 *= x1
133 ae += xe
134 }
135 x1 *= x1
136 xe <<= 1
137 if x1 < .5 {
138 x1 += x1
139 xe--
140 }
141 }
142
143
144
145
146 if y < 0 {
147 a1 = 1 / a1
148 ae = -ae
149 }
150 return Ldexp(a1, ae)
151 }
152
View as plain text