1// +build js
2
3package math
4
5import (
6	"github.com/gopherjs/gopherjs/js"
7)
8
9var math = js.Global.Get("Math")
10var zero float64 = 0
11var posInf = 1 / zero
12var negInf = -1 / zero
13var nan = 0 / zero
14
15func Acos(x float64) float64 {
16	return math.Call("acos", x).Float()
17}
18
19func Acosh(x float64) float64 {
20	return math.Call("acosh", x).Float()
21}
22
23func Asin(x float64) float64 {
24	return math.Call("asin", x).Float()
25}
26
27func Asinh(x float64) float64 {
28	return math.Call("asinh", x).Float()
29}
30
31func Atan(x float64) float64 {
32	return math.Call("atan", x).Float()
33}
34
35func Atanh(x float64) float64 {
36	return math.Call("atanh", x).Float()
37}
38
39func Atan2(y, x float64) float64 {
40	return math.Call("atan2", y, x).Float()
41}
42
43func Cbrt(x float64) float64 {
44	return math.Call("cbrt", x).Float()
45}
46
47func Ceil(x float64) float64 {
48	return math.Call("ceil", x).Float()
49}
50
51func Copysign(x, y float64) float64 {
52	if (x < 0 || 1/x == negInf) != (y < 0 || 1/y == negInf) {
53		return -x
54	}
55	return x
56}
57
58func Cos(x float64) float64 {
59	return math.Call("cos", x).Float()
60}
61
62func Cosh(x float64) float64 {
63	return math.Call("cosh", x).Float()
64}
65
66func Erf(x float64) float64 {
67	return erf(x)
68}
69
70func Erfc(x float64) float64 {
71	return erfc(x)
72}
73
74func Exp(x float64) float64 {
75	return math.Call("exp", x).Float()
76}
77
78func Exp2(x float64) float64 {
79	return math.Call("pow", 2, x).Float()
80}
81
82func Expm1(x float64) float64 {
83	return expm1(x)
84}
85
86func Floor(x float64) float64 {
87	return math.Call("floor", x).Float()
88}
89
90func Frexp(f float64) (frac float64, exp int) {
91	return frexp(f)
92}
93
94func Hypot(p, q float64) float64 {
95	return hypot(p, q)
96}
97
98func Inf(sign int) float64 {
99	switch {
100	case sign >= 0:
101		return posInf
102	default:
103		return negInf
104	}
105}
106
107func IsInf(f float64, sign int) bool {
108	if f == posInf {
109		return sign >= 0
110	}
111	if f == negInf {
112		return sign <= 0
113	}
114	return false
115}
116
117func IsNaN(f float64) (is bool) {
118	return f != f
119}
120
121func Ldexp(frac float64, exp int) float64 {
122	if frac == 0 {
123		return frac
124	}
125	if exp >= 1024 {
126		return frac * math.Call("pow", 2, 1023).Float() * math.Call("pow", 2, exp-1023).Float()
127	}
128	if exp <= -1024 {
129		return frac * math.Call("pow", 2, -1023).Float() * math.Call("pow", 2, exp+1023).Float()
130	}
131	return frac * math.Call("pow", 2, exp).Float()
132}
133
134func Log(x float64) float64 {
135	if x != x { // workaround for optimizer bug in V8, remove at some point
136		return nan
137	}
138	return math.Call("log", x).Float()
139}
140
141func Log10(x float64) float64 {
142	return log10(x)
143}
144
145func Log1p(x float64) float64 {
146	return log1p(x)
147}
148
149func Log2(x float64) float64 {
150	return log2(x)
151}
152
153func Max(x, y float64) float64 {
154	return max(x, y)
155}
156
157func Min(x, y float64) float64 {
158	return min(x, y)
159}
160
161func Mod(x, y float64) float64 {
162	return js.Global.Call("$mod", x, y).Float()
163}
164
165func Modf(f float64) (float64, float64) {
166	if f == posInf || f == negInf {
167		return f, nan
168	}
169	if 1/f == negInf {
170		return f, f
171	}
172	frac := Mod(f, 1)
173	return f - frac, frac
174}
175
176func NaN() float64 {
177	return nan
178}
179
180func Pow(x, y float64) float64 {
181	if x == 1 || (x == -1 && (y == posInf || y == negInf)) {
182		return 1
183	}
184	return math.Call("pow", x, y).Float()
185}
186
187func Remainder(x, y float64) float64 {
188	return remainder(x, y)
189}
190
191func Signbit(x float64) bool {
192	return x < 0 || 1/x == negInf
193}
194
195func Sin(x float64) float64 {
196	return math.Call("sin", x).Float()
197}
198
199func Sinh(x float64) float64 {
200	return math.Call("sinh", x).Float()
201}
202
203func Sincos(x float64) (sin, cos float64) {
204	return Sin(x), Cos(x)
205}
206
207func Sqrt(x float64) float64 {
208	return math.Call("sqrt", x).Float()
209}
210
211func Tan(x float64) float64 {
212	return math.Call("tan", x).Float()
213}
214
215func Tanh(x float64) float64 {
216	return math.Call("tanh", x).Float()
217}
218
219func Trunc(x float64) float64 {
220	if x == posInf || x == negInf || x != x || 1/x == negInf {
221		return x
222	}
223	return float64(int(x))
224}
225
226var buf struct {
227	uint32array  [2]uint32
228	float32array [2]float32
229	float64array [1]float64
230}
231
232func init() {
233	ab := js.Global.Get("ArrayBuffer").New(8)
234	js.InternalObject(buf).Set("uint32array", js.Global.Get("Uint32Array").New(ab))
235	js.InternalObject(buf).Set("float32array", js.Global.Get("Float32Array").New(ab))
236	js.InternalObject(buf).Set("float64array", js.Global.Get("Float64Array").New(ab))
237}
238
239func Float32bits(f float32) uint32 {
240	buf.float32array[0] = f
241	return buf.uint32array[0]
242}
243
244func Float32frombits(b uint32) float32 {
245	buf.uint32array[0] = b
246	return buf.float32array[0]
247}
248
249func Float64bits(f float64) uint64 {
250	buf.float64array[0] = f
251	return uint64(buf.uint32array[1])<<32 + uint64(buf.uint32array[0])
252}
253
254func Float64frombits(b uint64) float64 {
255	buf.uint32array[0] = uint32(b)
256	buf.uint32array[1] = uint32(b >> 32)
257	return buf.float64array[0]
258}
259