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
41 switch {
42 case y == 0 || x == 1:
43 return 1
44 case y == 1:
45 return x
46 case y == 0.5:
47 return Sqrt(x)
48 case y == -0.5:
49 return 1 / Sqrt(x)
50 case x != x || y != y:
51 return NaN()
52 case x == 0:
53 switch {
54 case y < 0:
55 if isOddInt(y) {
56 return Copysign(Inf(1), x)
57 }
58 return Inf(1)
59 case y > 0:
60 if isOddInt(y) {
61 return x
62 }
63 return 0
64 }
65 case y > MaxFloat64 || y < -MaxFloat64:
66 switch {
67 case x == -1:
68 return 1
69 case (Fabs(x) < 1) == IsInf(y, 1):
70 return 0
71 default:
72 return Inf(1)
73 }
74 case x > MaxFloat64 || x < -MaxFloat64:
75 if IsInf(x, -1) {
76 return Pow(1/x, -y)
77 }
78 switch {
79 case y < 0:
80 return 0
81 case y > 0:
82 return Inf(1)
83 }
84 }
85
86 absy := y
87 flip := false
88 if absy < 0 {
89 absy = -absy
90 flip = true
91 }
92 yi, yf := Modf(absy)
93 if yf != 0 && x < 0 {
94 return NaN()
95 }
96 if yi >= 1<<63 {
97 return Exp(y * Log(x))
98 }
99
100
101 a1 := 1.0
102 ae := 0
103
104
105 if yf != 0 {
106 if yf > 0.5 {
107 yf--
108 yi++
109 }
110 a1 = Exp(yf * Log(x))
111 }
112
113
114
115
116
117 x1, xe := Frexp(x)
118 for i := int64(yi); i != 0; i >>= 1 {
119 if i&1 == 1 {
120 a1 *= x1
121 ae += xe
122 }
123 x1 *= x1
124 xe <<= 1
125 if x1 < .5 {
126 x1 += x1
127 xe--
128 }
129 }
130
131
132
133
134 if flip {
135 a1 = 1 / a1
136 ae = -ae
137 }
138 return Ldexp(a1, ae)
139 }