warpo 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/assemblyscript/std/README.md +5 -0
  2. package/assemblyscript/std/assembly/array.ts +542 -0
  3. package/assemblyscript/std/assembly/arraybuffer.ts +72 -0
  4. package/assemblyscript/std/assembly/builtins.ts +2312 -0
  5. package/assemblyscript/std/assembly/compat.ts +2 -0
  6. package/assemblyscript/std/assembly/dataview.ts +144 -0
  7. package/assemblyscript/std/assembly/date.ts +383 -0
  8. package/assemblyscript/std/assembly/diagnostics.ts +11 -0
  9. package/assemblyscript/std/assembly/error.ts +39 -0
  10. package/assemblyscript/std/assembly/function.ts +44 -0
  11. package/assemblyscript/std/assembly/iterator.ts +24 -0
  12. package/assemblyscript/std/assembly/map.ts +304 -0
  13. package/assemblyscript/std/assembly/math.ts +3401 -0
  14. package/assemblyscript/std/assembly/memory.ts +110 -0
  15. package/assemblyscript/std/assembly/number.ts +388 -0
  16. package/assemblyscript/std/assembly/object.ts +30 -0
  17. package/assemblyscript/std/assembly/polyfills.ts +24 -0
  18. package/assemblyscript/std/assembly/process.ts +7 -0
  19. package/assemblyscript/std/assembly/promise.ts +172 -0
  20. package/assemblyscript/std/assembly/reference.ts +48 -0
  21. package/assemblyscript/std/assembly/regexp.ts +16 -0
  22. package/assemblyscript/std/assembly/rt/common.ts +79 -0
  23. package/assemblyscript/std/assembly/rt/index-incremental.ts +4 -0
  24. package/assemblyscript/std/assembly/rt/index-radical.ts +4 -0
  25. package/assemblyscript/std/assembly/rt/index.d.ts +37 -0
  26. package/assemblyscript/std/assembly/rt/itcms.ts +415 -0
  27. package/assemblyscript/std/assembly/rt/tcms.ts +276 -0
  28. package/assemblyscript/std/assembly/rt/tlsf.ts +564 -0
  29. package/assemblyscript/std/assembly/rt.ts +71 -0
  30. package/assemblyscript/std/assembly/set.ts +261 -0
  31. package/assemblyscript/std/assembly/shared/feature.ts +69 -0
  32. package/assemblyscript/std/assembly/shared/host.ts +12 -0
  33. package/assemblyscript/std/assembly/shared/runtime.ts +9 -0
  34. package/assemblyscript/std/assembly/shared/target.ts +9 -0
  35. package/assemblyscript/std/assembly/shared/tsconfig.json +9 -0
  36. package/assemblyscript/std/assembly/shared/typeinfo.ts +72 -0
  37. package/assemblyscript/std/assembly/staticarray.ts +446 -0
  38. package/assemblyscript/std/assembly/string.ts +892 -0
  39. package/assemblyscript/std/assembly/symbol.ts +61 -0
  40. package/assemblyscript/std/assembly/table.ts +15 -0
  41. package/assemblyscript/std/assembly/tsconfig.json +4 -0
  42. package/assemblyscript/std/assembly/tuple.ts +36 -0
  43. package/assemblyscript/std/assembly/typedarray.ts +2000 -0
  44. package/assemblyscript/std/assembly/uri.ts +17 -0
  45. package/assemblyscript/std/assembly/util/bytes.ts +90 -0
  46. package/assemblyscript/std/assembly/util/casemap.ts +264 -0
  47. package/assemblyscript/std/assembly/util/error.ts +54 -0
  48. package/assemblyscript/std/assembly/util/hash.ts +117 -0
  49. package/assemblyscript/std/assembly/util/math.ts +1922 -0
  50. package/assemblyscript/std/assembly/util/memory.ts +309 -0
  51. package/assemblyscript/std/assembly/util/number.ts +884 -0
  52. package/assemblyscript/std/assembly/util/sort.ts +282 -0
  53. package/assemblyscript/std/assembly/util/string.ts +1075 -0
  54. package/assemblyscript/std/assembly/util/uri.ts +251 -0
  55. package/assemblyscript/std/assembly/vector.ts +3 -0
  56. package/dist/debug_server/debugSession.d.ts +1 -0
  57. package/dist/debug_server/debugSession.js +15 -6
  58. package/dist/debug_server/debugSession.js.map +1 -1
  59. package/dist/debug_server/debuggerWasmModule.d.ts +3 -0
  60. package/dist/debug_server/debuggerWasmModule.js +47 -2
  61. package/dist/debug_server/debuggerWasmModule.js.map +1 -1
  62. package/dist/debug_server/tests/debugSession.test.js +96 -0
  63. package/dist/debug_server/tests/debugSession.test.js.map +1 -1
  64. package/dist/debug_server/tests/testModule/debugger_closure_stepping.d.ts +1 -0
  65. package/dist/debug_server/tests/testModule/debugger_closure_stepping.js +12 -0
  66. package/dist/debug_server/tests/testModule/debugger_closure_stepping.js.map +1 -0
  67. package/dist/debug_server/tests/testModule/debugger_std_array.d.ts +1 -0
  68. package/dist/debug_server/tests/testModule/debugger_std_array.js +6 -0
  69. package/dist/debug_server/tests/testModule/debugger_std_array.js.map +1 -0
  70. package/dist/debug_server/tests/testModule/debugger_string_stepping.d.ts +1 -0
  71. package/dist/debug_server/tests/testModule/debugger_string_stepping.js +9 -0
  72. package/dist/debug_server/tests/testModule/debugger_string_stepping.js.map +1 -0
  73. package/package.json +7 -7
  74. package/warpo_extension/std/tsconfig.json +4 -0
  75. package/warpo_extension/std/warpo/ffi.ts +16 -0
  76. package/warpo_extension/std/warpo/test/comparison.ts +122 -0
  77. package/warpo_extension/std/warpo/test/env.ts +33 -0
  78. package/warpo_extension/std/warpo/test/expect.ts +101 -0
  79. package/warpo_extension/std/warpo/test/formatPrint.ts +99 -0
  80. package/warpo_extension/std/warpo/test/implement.ts +41 -0
  81. package/warpo_extension/std/warpo/test/index.d.ts +0 -0
  82. package/warpo_extension/std/warpo/test/index.ts +39 -0
  83. package/warpo_extension/std/warpo/test/mockInstrument.ts +26 -0
  84. package/warpo_extension/std/warpo/utf8/const_str.ts +17 -0
  85. package/warpo_extension/std/wasi_snapshot_preview1/LICENSE +202 -0
  86. package/warpo_extension/std/wasi_snapshot_preview1/README.md +1 -0
  87. package/warpo_extension/std/wasi_snapshot_preview1/bindings/wasi_snapshot_preview1.ts +1731 -0
  88. package/warpo_extension/std/wasi_snapshot_preview1/wasi_console.ts +96 -0
  89. package/warpo_extension/std/wasi_snapshot_preview1/wasi_crypto.ts +8 -0
  90. package/warpo_extension/std/wasi_snapshot_preview1/wasi_date.ts +13 -0
  91. package/warpo_extension/std/wasi_snapshot_preview1/wasi_internal.ts +119 -0
  92. package/warpo_extension/std/wasi_snapshot_preview1/wasi_performance.ts +11 -0
  93. package/warpo_extension/std/wasi_snapshot_preview1/wasi_process.ts +191 -0
@@ -0,0 +1,3401 @@
1
+ import {
2
+ pow_lut,
3
+ exp_lut,
4
+ exp2_lut,
5
+ log_lut,
6
+ log2_lut,
7
+ powf_lut,
8
+ expf_lut,
9
+ exp2f_lut,
10
+ logf_lut,
11
+ log2f_lut,
12
+ } from "./util/math";
13
+
14
+ import {
15
+ abs as builtin_abs,
16
+ ceil as builtin_ceil,
17
+ clz as builtin_clz,
18
+ copysign as builtin_copysign,
19
+ floor as builtin_floor,
20
+ max as builtin_max,
21
+ min as builtin_min,
22
+ sqrt as builtin_sqrt,
23
+ trunc as builtin_trunc,
24
+ } from "./builtins";
25
+
26
+ // SUN COPYRIGHT NOTICE
27
+ //
28
+ // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
29
+ // Developed at SunPro, a Sun Microsystems, Inc. business.
30
+ // Permission to use, copy, modify, and distribute this software
31
+ // is freely granted, provided that this notice is preserved.
32
+ //
33
+ // Applies to all functions marked with a comment referring here.
34
+
35
+ /** @internal */
36
+ // @ts-ignore: decorator
37
+ @lazy let rempio2_y0: f64, rempio2_y1: f64, res128_hi: u64;
38
+
39
+ /** @internal */
40
+ // @ts-ignore: decorator
41
+ @lazy @inline const PIO2_TABLE = memory.data<u64>([
42
+ 0x00000000a2f9836e, 0x4e441529fc2757d1, 0xf534ddc0db629599, 0x3c439041fe5163ab, 0xdebbc561b7246e3a,
43
+ 0x424dd2e006492eea, 0x09d1921cfe1deb1c, 0xb129a73ee88235f5, 0x2ebb4484e99c7026, 0xb45f7e413991d639,
44
+ 0x835339f49c845f8b, 0xbdf9283b1ff897ff, 0xde05980fef2f118b, 0x5a0a6d1f6d367ecf, 0x27cb09b74f463f66,
45
+ 0x9e5fea2d7527bac7, 0xebe5f17b3d0739f7, 0x8a5292ea6bfb5fb1, 0x1f8d5d0856033046, 0xfc7b6babf0cfbc20,
46
+ 0x9af4361da9e39161, 0x5ee61b086599855f, 0x14a068408dffd880, 0x4d73273106061557,
47
+ ]);
48
+
49
+ /** @internal */
50
+ function R(z: f64): f64 {
51
+ // Rational approximation of (asin(x)-x)/x^3
52
+ const // see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE above
53
+ pS0 = reinterpret<f64>(0x3fc5555555555555), // 1.66666666666666657415e-01
54
+ pS1 = reinterpret<f64>(0xbfd4d61203eb6f7d), // -3.25565818622400915405e-01
55
+ pS2 = reinterpret<f64>(0x3fc9c1550e884455), // 2.01212532134862925881e-01
56
+ pS3 = reinterpret<f64>(0xbfa48228b5688f3b), // -4.00555345006794114027e-02
57
+ pS4 = reinterpret<f64>(0x3f49efe07501b288), // 7.91534994289814532176e-04
58
+ pS5 = reinterpret<f64>(0x3f023de10dfdf709), // 3.47933107596021167570e-05
59
+ qS1 = reinterpret<f64>(0xc0033a271c8a2d4b), // -2.40339491173441421878e+00
60
+ qS2 = reinterpret<f64>(0x40002ae59c598ac8), // 2.02094576023350569471e+00
61
+ qS3 = reinterpret<f64>(0xbfe6066c1b8d0159), // -6.88283971605453293030e-01
62
+ qS4 = reinterpret<f64>(0x3fb3b8c5b12e9282); // 7.70381505559019352791e-02
63
+
64
+ let p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
65
+ let q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
66
+ return p / q;
67
+ }
68
+
69
+ /** @internal */
70
+ // @ts-ignore: decorator
71
+ @inline
72
+ function expo2(x: f64, sign: f64): f64 {
73
+ // exp(x)/2 for x >= log(DBL_MAX)
74
+ const // see: musl/src/math/__expo2.c
75
+ k = <u32>2043,
76
+ kln2 = reinterpret<f64>(0x40962066151add8b); // 0x1.62066151add8bp+10
77
+ let scale = reinterpret<f64>((<u64>((<u32>0x3ff + k / 2) << 20)) << 32);
78
+ // in directed rounding correct sign before rounding or overflow is important
79
+ return NativeMath.exp(x - kln2) * (sign * scale) * scale;
80
+ }
81
+
82
+ /** @internal */
83
+ /* Helper function to eventually get bits of π/2 * |x|
84
+ *
85
+ * y = π/4 * (frac << clz(frac) >> 11)
86
+ * return clz(frac)
87
+ *
88
+ * Right shift 11 bits to make upper half fit in `double`
89
+ */
90
+ // @ts-ignore: decorator
91
+ @inline
92
+ function pio2_right(q0: u64, q1: u64): u64 {
93
+ // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c
94
+ // Bits of π/4
95
+ const p0: u64 = 0xc4c6628b80dc1cd1;
96
+ const p1: u64 = 0xc90fdaa22168c234;
97
+
98
+ const Ox1p_64 = reinterpret<f64>(0x3bf0000000000000); // 0x1p-64
99
+ const Ox1p_75 = reinterpret<f64>(0x3b40000000000000); // 0x1p-75
100
+
101
+ let shift = clz(q1);
102
+
103
+ q1 = (q1 << shift) | (q0 >> (64 - shift));
104
+ q0 <<= shift;
105
+
106
+ let lo = umuldi(p1, q1);
107
+ let hi = res128_hi;
108
+
109
+ let ahi = hi >> 11;
110
+ let alo = (lo >> 11) | (hi << 53);
111
+ let blo = <u64>(Ox1p_75 * <f64>p0 * <f64>q1 + Ox1p_75 * <f64>p1 * <f64>q0);
112
+
113
+ rempio2_y0 = <f64>(ahi + u64(lo < blo));
114
+ rempio2_y1 = Ox1p_64 * <f64>(alo + blo);
115
+
116
+ return shift;
117
+ }
118
+
119
+ /** @internal */
120
+ // @ts-ignore: decorator
121
+ @inline
122
+ function umuldi(u: u64, v: u64): u64 {
123
+ let u1: u64, v1: u64, w0: u64, w1: u64, t: u64;
124
+
125
+ u1 = u & 0xffffffff;
126
+ v1 = v & 0xffffffff;
127
+
128
+ u >>= 32;
129
+ v >>= 32;
130
+
131
+ t = u1 * v1;
132
+ w0 = t & 0xffffffff;
133
+ t = u * v1 + (t >> 32);
134
+ w1 = t >> 32;
135
+ t = u1 * v + (t & 0xffffffff);
136
+
137
+ res128_hi = u * v + w1 + (t >> 32);
138
+ return (t << 32) + w0;
139
+ }
140
+
141
+ /** @internal */
142
+ function pio2_large_quot(x: f64, u: i64): i32 {
143
+ // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c
144
+ let magnitude = u & 0x7fffffffffffffff;
145
+ let offset = (magnitude >> 52) - 1045;
146
+ let shift = offset & 63;
147
+ let tblPtr = PIO2_TABLE + ((<i32>(offset >> 6)) << 3);
148
+ let s0: u64, s1: u64, s2: u64;
149
+
150
+ let b0 = load<u64>(tblPtr, 0 << 3);
151
+ let b1 = load<u64>(tblPtr, 1 << 3);
152
+ let b2 = load<u64>(tblPtr, 2 << 3);
153
+
154
+ // Get 192 bits of 0x1p-31 / π with `offset` bits skipped
155
+ if (shift) {
156
+ let rshift = 64 - shift;
157
+ let b3 = load<u64>(tblPtr, 3 << 3);
158
+ s0 = (b1 >> rshift) | (b0 << shift);
159
+ s1 = (b2 >> rshift) | (b1 << shift);
160
+ s2 = (b3 >> rshift) | (b2 << shift);
161
+ } else {
162
+ s0 = b0;
163
+ s1 = b1;
164
+ s2 = b2;
165
+ }
166
+
167
+ let significand = (u & 0x000fffffffffffff) | 0x0010000000000000;
168
+
169
+ // First 128 bits of fractional part of x/(2π)
170
+ let blo = umuldi(s1, significand);
171
+ let bhi = res128_hi;
172
+
173
+ let ahi = s0 * significand;
174
+ let clo = (s2 >> 32) * (significand >> 32);
175
+ let plo = blo + clo;
176
+ let phi = ahi + bhi + u64(plo < clo);
177
+
178
+ // r: u128 = p << 2
179
+ let rlo = plo << 2;
180
+ let rhi = (phi << 2) | (plo >> 62);
181
+
182
+ // s: i128 = r >> 127
183
+ let slo = (<i64>rhi) >> 63;
184
+ let shi = slo >> 1;
185
+ let q = ((<i64>phi) >> 62) - slo;
186
+
187
+ let shifter = 0x3cb0000000000000 - (pio2_right(rlo ^ slo, rhi ^ shi) << 52);
188
+ let signbit = (u ^ rhi) & 0x8000000000000000;
189
+ let coeff = reinterpret<f64>(shifter | signbit);
190
+
191
+ rempio2_y0 *= coeff;
192
+ rempio2_y1 *= coeff;
193
+
194
+ return <i32>q;
195
+ }
196
+
197
+ /** @internal */
198
+ // @ts-ignore: decorator
199
+ @inline
200
+ function rempio2(x: f64, u: u64, sign: i32): i32 {
201
+ const pio2_1 = reinterpret<f64>(0x3ff921fb54400000), // 1.57079632673412561417e+00
202
+ pio2_1t = reinterpret<f64>(0x3dd0b4611a626331), // 6.07710050650619224932e-11
203
+ pio2_2 = reinterpret<f64>(0x3dd0b4611a600000), // 6.07710050630396597660e-11
204
+ pio2_2t = reinterpret<f64>(0x3ba3198a2e037073), // 2.02226624879595063154e-21
205
+ pio2_3 = reinterpret<f64>(0x3ba3198a2e000000), // 2.02226624871116645580e-21
206
+ pio2_3t = reinterpret<f64>(0x397b839a252049c1), // 8.47842766036889956997e-32
207
+ invpio2 = reinterpret<f64>(0x3fe45f306dc9c883); // 0.63661977236758134308
208
+
209
+ let ix = (<u32>(u >> 32)) & 0x7fffffff;
210
+
211
+ if (ASC_SHRINK_LEVEL < 1) {
212
+ if (ix < 0x4002d97c) {
213
+ // |x| < 3pi/4, special case with n=+-1
214
+ let q = 1,
215
+ z: f64,
216
+ y0: f64,
217
+ y1: f64;
218
+ if (!sign) {
219
+ z = x - pio2_1;
220
+ if (ix != 0x3ff921fb) {
221
+ // 33+53 bit pi is good enough
222
+ y0 = z - pio2_1t;
223
+ y1 = z - y0 - pio2_1t;
224
+ } else {
225
+ // near pi/2, use 33+33+53 bit pi
226
+ z -= pio2_2;
227
+ y0 = z - pio2_2t;
228
+ y1 = z - y0 - pio2_2t;
229
+ }
230
+ } else {
231
+ // negative x
232
+ z = x + pio2_1;
233
+ if (ix != 0x3ff921fb) {
234
+ // 33+53 bit pi is good enough
235
+ y0 = z + pio2_1t;
236
+ y1 = z - y0 + pio2_1t;
237
+ } else {
238
+ // near pi/2, use 33+33+53 bit pi
239
+ z += pio2_2;
240
+ y0 = z + pio2_2t;
241
+ y1 = z - y0 + pio2_2t;
242
+ }
243
+ q = -1;
244
+ }
245
+ rempio2_y0 = y0;
246
+ rempio2_y1 = y1;
247
+ return q;
248
+ }
249
+ }
250
+
251
+ if (ix < 0x413921fb) {
252
+ // |x| ~< 2^20*pi/2 (1647099)
253
+ // Use precise Cody Waite scheme
254
+ let q = nearest(x * invpio2);
255
+ let r = x - q * pio2_1;
256
+ let w = q * pio2_1t; // 1st round good to 85 bit
257
+ let j = ix >> 20;
258
+ let y0 = r - w;
259
+ let hi = <u32>(reinterpret<u64>(y0) >> 32);
260
+ let i = j - ((hi >> 20) & 0x7ff);
261
+
262
+ if (i > 16) {
263
+ // 2nd iteration needed, good to 118
264
+ let t = r;
265
+ w = q * pio2_2;
266
+ r = t - w;
267
+ w = q * pio2_2t - (t - r - w);
268
+ y0 = r - w;
269
+ hi = <u32>(reinterpret<u64>(y0) >> 32);
270
+ i = j - ((hi >> 20) & 0x7ff);
271
+ if (i > 49) {
272
+ // 3rd iteration need, 151 bits acc
273
+ let t = r;
274
+ w = q * pio2_3;
275
+ r = t - w;
276
+ w = q * pio2_3t - (t - r - w);
277
+ y0 = r - w;
278
+ }
279
+ }
280
+ let y1 = r - y0 - w;
281
+ rempio2_y0 = y0;
282
+ rempio2_y1 = y1;
283
+ return <i32>q;
284
+ }
285
+ let q = pio2_large_quot(x, u);
286
+ return select(-q, q, sign);
287
+ }
288
+
289
+ /** @internal */
290
+ // @ts-ignore: decorator
291
+ @inline
292
+ function sin_kern(x: f64, y: f64, iy: i32): f64 {
293
+ // see: musl/tree/src/math/__sin.c
294
+ const S1 = reinterpret<f64>(0xbfc5555555555549), // -1.66666666666666324348e-01
295
+ S2 = reinterpret<f64>(0x3f8111111110f8a6), // 8.33333333332248946124e-03
296
+ S3 = reinterpret<f64>(0xbf2a01a019c161d5), // -1.98412698298579493134e-04
297
+ S4 = reinterpret<f64>(0x3ec71de357b1fe7d), // 2.75573137070700676789e-06
298
+ S5 = reinterpret<f64>(0xbe5ae5e68a2b9ceb), // -2.50507602534068634195e-08
299
+ S6 = reinterpret<f64>(0x3de5d93a5acfd57c); // 1.58969099521155010221e-10
300
+
301
+ let z = x * x;
302
+ let w = z * z;
303
+ let r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6);
304
+ let v = z * x;
305
+ if (!iy) {
306
+ return x + v * (S1 + z * r);
307
+ } else {
308
+ return x - (z * (0.5 * y - v * r) - y - v * S1);
309
+ }
310
+ }
311
+
312
+ /** @internal */
313
+ // @ts-ignore: decorator
314
+ @inline
315
+ function cos_kern(x: f64, y: f64): f64 {
316
+ // see: musl/tree/src/math/__cos.c
317
+ const C1 = reinterpret<f64>(0x3fa555555555554c), // 4.16666666666666019037e-02
318
+ C2 = reinterpret<f64>(0xbf56c16c16c15177), // -1.38888888888741095749e-03
319
+ C3 = reinterpret<f64>(0x3efa01a019cb1590), // 2.48015872894767294178e-05
320
+ C4 = reinterpret<f64>(0xbe927e4f809c52ad), // -2.75573143513906633035e-07
321
+ C5 = reinterpret<f64>(0x3e21ee9ebdb4b1c4), // 2.08757232129817482790e-09
322
+ C6 = reinterpret<f64>(0xbda8fae9be8838d4); // -1.13596475577881948265e-11
323
+
324
+ let z = x * x;
325
+ let w = z * z;
326
+ let r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6));
327
+ let hz = 0.5 * z;
328
+ w = 1.0 - hz;
329
+ return w + (1.0 - w - hz + (z * r - x * y));
330
+ }
331
+
332
+ /** @internal */
333
+ function tan_kern(x: f64, y: f64, iy: i32): f64 {
334
+ // see: src/lib/msun/src/k_tan.c
335
+ const T0 = reinterpret<f64>(0x3fd5555555555563), // 3.33333333333334091986e-01
336
+ T1 = reinterpret<f64>(0x3fc111111110fe7a), // 1.33333333333201242699e-01
337
+ T2 = reinterpret<f64>(0x3faba1ba1bb341fe), // 5.39682539762260521377e-02
338
+ T3 = reinterpret<f64>(0x3f9664f48406d637), // 2.18694882948595424599e-02
339
+ T4 = reinterpret<f64>(0x3f8226e3e96e8493), // 8.86323982359930005737e-03
340
+ T5 = reinterpret<f64>(0x3f6d6d22c9560328), // 3.59207910759131235356e-03
341
+ T6 = reinterpret<f64>(0x3f57dbc8fee08315), // 1.45620945432529025516e-03
342
+ T7 = reinterpret<f64>(0x3f4344d8f2f26501), // 5.88041240820264096874e-04
343
+ T8 = reinterpret<f64>(0x3f3026f71a8d1068), // 2.46463134818469906812e-04
344
+ T9 = reinterpret<f64>(0x3f147e88a03792a6), // 7.81794442939557092300e-05
345
+ T10 = reinterpret<f64>(0x3f12b80f32f0a7e9), // 7.14072491382608190305e-05
346
+ T11 = reinterpret<f64>(0xbef375cbdb605373), // -1.85586374855275456654e-05
347
+ T12 = reinterpret<f64>(0x3efb2a7074bf7ad4); // 2.59073051863633712884e-05
348
+
349
+ const one = reinterpret<f64>(0x3ff0000000000000), // 1.00000000000000000000e+00
350
+ pio4 = reinterpret<f64>(0x3fe921fb54442d18), // 7.85398163397448278999e-01
351
+ pio4lo = reinterpret<f64>(0x3c81a62633145c07); // 3.06161699786838301793e-17
352
+
353
+ let z: f64, r: f64, v: f64, w: f64, s: f64;
354
+ let hx = <i32>(reinterpret<u64>(x) >> 32); // high word of x
355
+ let ix = hx & 0x7fffffff; // high word of |x|
356
+ let big = ix >= 0x3fe59428;
357
+ if (big) {
358
+ // |x| >= 0.6744
359
+ if (hx < 0) {
360
+ ((x = -x), (y = -y));
361
+ }
362
+ z = pio4 - x;
363
+ w = pio4lo - y;
364
+ x = z + w;
365
+ y = 0.0;
366
+ }
367
+ z = x * x;
368
+ w = z * z;
369
+ r = T1 + w * (T3 + w * (T5 + w * (T7 + w * (T9 + w * T11))));
370
+ v = z * (T2 + w * (T4 + w * (T6 + w * (T8 + w * (T10 + w * T12)))));
371
+ s = z * x;
372
+ r = y + z * (s * (r + v) + y);
373
+ r += T0 * s;
374
+ w = x + r;
375
+ if (big) {
376
+ v = iy;
377
+ return (1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - ((w * w) / (w + v) - r)));
378
+ }
379
+ if (iy == 1) return w;
380
+ let a: f64, t: f64;
381
+ z = w;
382
+ z = reinterpret<f64>(reinterpret<u64>(z) & 0xffffffff00000000);
383
+ v = r - (z - x); // z + v = r + x
384
+ t = a = -one / w; // a = -1.0 / w
385
+ t = reinterpret<f64>(reinterpret<u64>(t) & 0xffffffff00000000);
386
+ s = one + t * z;
387
+ return t + a * (s + t * v);
388
+ }
389
+
390
+ /** @internal */
391
+ function dtoi32(x: f64): i32 {
392
+ if (ASC_SHRINK_LEVEL > 0) {
393
+ const inv32 = 1.0 / 4294967296;
394
+ return <i32>(<i64>(x - 4294967296 * floor(x * inv32)));
395
+ } else {
396
+ let result = 0;
397
+ let u = reinterpret<u64>(x);
398
+ let e = (u >> 52) & 0x7ff;
399
+ if (e <= 1023 + 30) {
400
+ result = <i32>x;
401
+ } else if (e <= 1023 + 30 + 53) {
402
+ let v = (u & (((<u64>1) << 52) - 1)) | ((<u64>1) << 52);
403
+ v = v << (e - 1023 - 52 + 32);
404
+ result = <i32>(v >> 32);
405
+ result = select<i32>(-result, result, <i64>u < 0);
406
+ }
407
+ return result;
408
+ }
409
+ }
410
+
411
+ // @ts-ignore: decorator
412
+ @lazy let random_seeded = false;
413
+
414
+ // @ts-ignore: decorator
415
+ @lazy let random_state0_64: u64, random_state1_64: u64;
416
+
417
+ // @ts-ignore: decorator
418
+ @lazy let random_state0_32: u32, random_state1_32: u32;
419
+
420
+ function murmurHash3(h: u64): u64 {
421
+ // Force all bits of a hash block to avalanche
422
+ h ^= h >> 33; // see: https://github.com/aappleby/smhasher
423
+ h *= 0xff51afd7ed558ccd;
424
+ h ^= h >> 33;
425
+ h *= 0xc4ceb9fe1a85ec53;
426
+ h ^= h >> 33;
427
+ return h;
428
+ }
429
+
430
+ function splitMix32(h: u32): u32 {
431
+ h += 0x6d2b79f5;
432
+ h = (h ^ (h >> 15)) * (h | 1);
433
+ h ^= h + (h ^ (h >> 7)) * (h | 61);
434
+ return h ^ (h >> 14);
435
+ }
436
+
437
+ export namespace NativeMath {
438
+ // @ts-ignore: decorator
439
+ @lazy
440
+ export const E = reinterpret<f64>(0x4005bf0a8b145769); // 2.7182818284590452354
441
+
442
+ // @ts-ignore: decorator
443
+ @lazy
444
+ export const LN2 = reinterpret<f64>(0x3fe62e42fefa39ef); // 0.69314718055994530942
445
+
446
+ // @ts-ignore: decorator
447
+ @lazy
448
+ export const LN10 = reinterpret<f64>(0x40026bb1bbb55516); // 2.30258509299404568402
449
+
450
+ // @ts-ignore: decorator
451
+ @lazy
452
+ export const LOG2E = reinterpret<f64>(0x3ff71547652b82fe); // 1.4426950408889634074
453
+
454
+ // @ts-ignore: decorator
455
+ @lazy
456
+ export const LOG10E = reinterpret<f64>(0x3fdbcb7b1526e50e); // 0.43429448190325182765
457
+
458
+ // @ts-ignore: decorator
459
+ @lazy
460
+ export const PI = reinterpret<f64>(0x400921fb54442d18); // 3.14159265358979323846
461
+
462
+ // @ts-ignore: decorator
463
+ @lazy
464
+ export const SQRT1_2 = reinterpret<f64>(0x3fe6a09e667f3bcd); // 0.70710678118654752440
465
+
466
+ // @ts-ignore: decorator
467
+ @lazy
468
+ export const SQRT2 = reinterpret<f64>(0x3ff6a09e667f3bcd); // 1.41421356237309504880
469
+
470
+ // @ts-ignore: decorator
471
+ @lazy
472
+ export let sincos_sin: f64 = 0;
473
+
474
+ // @ts-ignore: decorator
475
+ @lazy
476
+ export let sincos_cos: f64 = 0;
477
+
478
+ // @ts-ignore: decorator
479
+ @inline export function abs(x: f64): f64 {
480
+ return builtin_abs<f64>(x);
481
+ }
482
+
483
+ export function acos(x: f64): f64 {
484
+ // see: musl/src/math/acos.c and SUN COPYRIGHT NOTICE above
485
+ const pio2_hi = reinterpret<f64>(0x3ff921fb54442d18), // 1.57079632679489655800e+00
486
+ pio2_lo = reinterpret<f64>(0x3c91a62633145c07), // 6.12323399573676603587e-17
487
+ Ox1p_120f = reinterpret<f32>(0x03800000);
488
+
489
+ let hx = <u32>(reinterpret<u64>(x) >> 32);
490
+ let ix = hx & 0x7fffffff;
491
+ if (ix >= 0x3ff00000) {
492
+ let lx = <u32>reinterpret<u64>(x);
493
+ if (((ix - 0x3ff00000) | lx) == 0) {
494
+ if (<i32>hx < 0) return 2 * pio2_hi + Ox1p_120f;
495
+ return 0;
496
+ }
497
+ return 0 / (x - x);
498
+ }
499
+ if (ix < 0x3fe00000) {
500
+ if (ix <= 0x3c600000) return pio2_hi + Ox1p_120f;
501
+ return pio2_hi - (x - (pio2_lo - x * R(x * x)));
502
+ }
503
+ let s: f64, w: f64, z: f64;
504
+ if (<i32>hx < 0) {
505
+ // z = (1.0 + x) * 0.5;
506
+ z = 0.5 + x * 0.5;
507
+ s = builtin_sqrt<f64>(z);
508
+ w = R(z) * s - pio2_lo;
509
+ return 2 * (pio2_hi - (s + w));
510
+ }
511
+ // z = (1.0 - x) * 0.5;
512
+ z = 0.5 - x * 0.5;
513
+ s = builtin_sqrt<f64>(z);
514
+ let df = reinterpret<f64>(reinterpret<u64>(s) & 0xffffffff00000000);
515
+ let c = (z - df * df) / (s + df);
516
+ w = R(z) * s + c;
517
+ return 2 * (df + w);
518
+ }
519
+
520
+ export function acosh(x: f64): f64 {
521
+ // see: musl/src/math/acosh.c
522
+ const s = reinterpret<f64>(0x3fe62e42fefa39ef);
523
+ let u = reinterpret<u64>(x);
524
+ // Prevent propagation for all input values less than 1.0.
525
+ // Note musl lib didn't fix this yet.
526
+ if (<i64>u < 0x3ff0000000000000) return (x - x) / 0.0;
527
+ let e = (u >> 52) & 0x7ff;
528
+ if (e < 0x3ff + 1) return log1p(x - 1 + builtin_sqrt<f64>((x - 1) * (x - 1) + 2 * (x - 1)));
529
+ if (e < 0x3ff + 26) return log(2 * x - 1 / (x + builtin_sqrt<f64>(x * x - 1)));
530
+ return log(x) + s;
531
+ }
532
+
533
+ export function asin(x: f64): f64 {
534
+ // see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE above
535
+ const pio2_hi = reinterpret<f64>(0x3ff921fb54442d18), // 1.57079632679489655800e+00
536
+ pio2_lo = reinterpret<f64>(0x3c91a62633145c07), // 6.12323399573676603587e-17
537
+ Ox1p_120f = reinterpret<f32>(0x03800000);
538
+
539
+ let hx = <u32>(reinterpret<u64>(x) >> 32);
540
+ let ix = hx & 0x7fffffff;
541
+ if (ix >= 0x3ff00000) {
542
+ let lx = <u32>reinterpret<u64>(x);
543
+ if (((ix - 0x3ff00000) | lx) == 0) return x * pio2_hi + Ox1p_120f;
544
+ return 0 / (x - x);
545
+ }
546
+ if (ix < 0x3fe00000) {
547
+ if (ix < 0x3e500000 && ix >= 0x00100000) return x;
548
+ return x + x * R(x * x);
549
+ }
550
+ // let z = (1.0 - builtin_abs<f64>(x)) * 0.5;
551
+ let z = 0.5 - builtin_abs<f64>(x) * 0.5;
552
+ let s = builtin_sqrt<f64>(z);
553
+ let r = R(z);
554
+ if (ix >= 0x3fef3333) x = pio2_hi - (2 * (s + s * r) - pio2_lo);
555
+ else {
556
+ let f = reinterpret<f64>(reinterpret<u64>(s) & 0xffffffff00000000);
557
+ let c = (z - f * f) / (s + f);
558
+ x = 0.5 * pio2_hi - (2 * s * r - (pio2_lo - 2 * c) - (0.5 * pio2_hi - 2 * f));
559
+ }
560
+ return select(-x, x, <i32>hx < 0);
561
+ }
562
+
563
+ export function asinh(x: f64): f64 {
564
+ // see: musl/src/math/asinh.c
565
+ const c = reinterpret<f64>(0x3fe62e42fefa39ef); // 0.693147180559945309417232121458176568
566
+ let u = reinterpret<u64>(x);
567
+ let e = (u >> 52) & 0x7ff;
568
+ let y = reinterpret<f64>(u & 0x7fffffffffffffff);
569
+ if (e >= 0x3ff + 26) y = log(y) + c;
570
+ else if (e >= 0x3ff + 1) y = log(2 * y + 1 / (builtin_sqrt<f64>(y * y + 1) + y));
571
+ else if (e >= 0x3ff - 26) y = log1p(y + (y * y) / (builtin_sqrt<f64>(y * y + 1) + 1));
572
+ return builtin_copysign(y, x);
573
+ }
574
+
575
+ export function atan(x: f64): f64 {
576
+ // see musl/src/math/atan.c and SUN COPYRIGHT NOTICE above
577
+ const atanhi0 = reinterpret<f64>(0x3fddac670561bb4f), // 4.63647609000806093515e-01
578
+ atanhi1 = reinterpret<f64>(0x3fe921fb54442d18), // 7.85398163397448278999e-01
579
+ atanhi2 = reinterpret<f64>(0x3fef730bd281f69b), // 9.82793723247329054082e-01
580
+ atanhi3 = reinterpret<f64>(0x3ff921fb54442d18), // 1.57079632679489655800e+00
581
+ atanlo0 = reinterpret<f64>(0x3c7a2b7f222f65e2), // 2.26987774529616870924e-17
582
+ atanlo1 = reinterpret<f64>(0x3c81a62633145c07), // 3.06161699786838301793e-17
583
+ atanlo2 = reinterpret<f64>(0x3c7007887af0cbbd), // 1.39033110312309984516e-17
584
+ atanlo3 = reinterpret<f64>(0x3c91a62633145c07), // 6.12323399573676603587e-17
585
+ aT0 = reinterpret<f64>(0x3fd555555555550d), // 3.33333333333329318027e-01
586
+ aT1 = reinterpret<f64>(0xbfc999999998ebc4), // -1.99999999998764832476e-01
587
+ aT2 = reinterpret<f64>(0x3fc24924920083ff), // 1.42857142725034663711e-01
588
+ aT3 = reinterpret<f64>(0xbfbc71c6fe231671), // -1.11111104054623557880e-01,
589
+ aT4 = reinterpret<f64>(0x3fb745cdc54c206e), // 9.09088713343650656196e-02
590
+ aT5 = reinterpret<f64>(0xbfb3b0f2af749a6d), // -7.69187620504482999495e-02
591
+ aT6 = reinterpret<f64>(0x3fb10d66a0d03d51), // 6.66107313738753120669e-02
592
+ aT7 = reinterpret<f64>(0xbfadde2d52defd9a), // -5.83357013379057348645e-02
593
+ aT8 = reinterpret<f64>(0x3fa97b4b24760deb), // 4.97687799461593236017e-02
594
+ aT9 = reinterpret<f64>(0xbfa2b4442c6a6c2f), // -3.65315727442169155270e-02
595
+ aT10 = reinterpret<f64>(0x3f90ad3ae322da11), // 1.62858201153657823623e-02
596
+ Ox1p_120f = reinterpret<f32>(0x03800000);
597
+
598
+ let ix = <u32>(reinterpret<u64>(x) >> 32);
599
+ let sx = x;
600
+ ix &= 0x7fffffff;
601
+ let z: f64;
602
+ if (ix >= 0x44100000) {
603
+ if (isNaN(x)) return x;
604
+ z = atanhi3 + Ox1p_120f;
605
+ return builtin_copysign<f64>(z, sx);
606
+ }
607
+ let id: i32;
608
+ if (ix < 0x3fdc0000) {
609
+ if (ix < 0x3e400000) return x;
610
+ id = -1;
611
+ } else {
612
+ x = builtin_abs<f64>(x);
613
+ if (ix < 0x3ff30000) {
614
+ if (ix < 0x3fe60000) {
615
+ id = 0;
616
+ x = (2.0 * x - 1.0) / (2.0 + x);
617
+ } else {
618
+ id = 1;
619
+ x = (x - 1.0) / (x + 1.0);
620
+ }
621
+ } else {
622
+ if (ix < 0x40038000) {
623
+ id = 2;
624
+ x = (x - 1.5) / (1.0 + 1.5 * x);
625
+ } else {
626
+ id = 3;
627
+ x = -1.0 / x;
628
+ }
629
+ }
630
+ }
631
+ z = x * x;
632
+ let w = z * z;
633
+ let s1 = z * (aT0 + w * (aT2 + w * (aT4 + w * (aT6 + w * (aT8 + w * aT10)))));
634
+ let s2 = w * (aT1 + w * (aT3 + w * (aT5 + w * (aT7 + w * aT9))));
635
+ let s3 = x * (s1 + s2);
636
+ if (id < 0) return x - s3;
637
+ switch (id) {
638
+ case 0: {
639
+ z = atanhi0 - (s3 - atanlo0 - x);
640
+ break;
641
+ }
642
+ case 1: {
643
+ z = atanhi1 - (s3 - atanlo1 - x);
644
+ break;
645
+ }
646
+ case 2: {
647
+ z = atanhi2 - (s3 - atanlo2 - x);
648
+ break;
649
+ }
650
+ case 3: {
651
+ z = atanhi3 - (s3 - atanlo3 - x);
652
+ break;
653
+ }
654
+ default:
655
+ unreachable();
656
+ }
657
+ return builtin_copysign<f64>(z, sx);
658
+ }
659
+
660
+ export function atanh(x: f64): f64 {
661
+ // see: musl/src/math/atanh.c
662
+ let u = reinterpret<u64>(x);
663
+ let e = (u >> 52) & 0x7ff;
664
+ let y = builtin_abs(x);
665
+ if (e < 0x3ff - 1) {
666
+ if (e >= 0x3ff - 32) y = 0.5 * log1p(2 * y + (2 * y * y) / (1 - y));
667
+ } else {
668
+ y = 0.5 * log1p(2 * (y / (1 - y)));
669
+ }
670
+ return builtin_copysign<f64>(y, x);
671
+ }
672
+
673
+ export function atan2(y: f64, x: f64): f64 {
674
+ // see: musl/src/math/atan2.c and SUN COPYRIGHT NOTICE above
675
+ const pi_lo = reinterpret<f64>(0x3ca1a62633145c07); // 1.2246467991473531772E-16
676
+ if (isNaN(x) || isNaN(y)) return x + y;
677
+ let u = reinterpret<u64>(x);
678
+ let ix = <u32>(u >> 32);
679
+ let lx = <u32>u;
680
+ u = reinterpret<u64>(y);
681
+ let iy = <u32>(u >> 32);
682
+ let ly = <u32>u;
683
+ if (((ix - 0x3ff00000) | lx) == 0) return atan(y);
684
+ let m = ((iy >> 31) & 1) | ((ix >> 30) & 2);
685
+ ix = ix & 0x7fffffff;
686
+ iy = iy & 0x7fffffff;
687
+ if ((iy | ly) == 0) {
688
+ switch (m) {
689
+ case 0:
690
+ case 1:
691
+ return y;
692
+ case 2:
693
+ return PI;
694
+ case 3:
695
+ return -PI;
696
+ }
697
+ }
698
+ if ((ix | lx) == 0) return m & 1 ? -PI / 2 : PI / 2;
699
+ if (ix == 0x7ff00000) {
700
+ if (iy == 0x7ff00000) {
701
+ let t = m & 2 ? (3 * PI) / 4 : PI / 4;
702
+ return m & 1 ? -t : t;
703
+ } else {
704
+ let t = m & 2 ? PI : 0;
705
+ return m & 1 ? -t : t;
706
+ }
707
+ }
708
+ let z: f64;
709
+ if (ix + (64 << 20) < iy || iy == 0x7ff00000) return m & 1 ? -PI / 2 : PI / 2;
710
+ if (m & 2 && iy + (64 << 20) < ix) z = 0;
711
+ else z = atan(builtin_abs<f64>(y / x));
712
+ switch (m) {
713
+ case 0:
714
+ return z;
715
+ case 1:
716
+ return -z;
717
+ case 2:
718
+ return PI - (z - pi_lo);
719
+ case 3:
720
+ return z - pi_lo - PI;
721
+ }
722
+ unreachable();
723
+ return 0;
724
+ }
725
+
726
+ export function cbrt(x: f64): f64 {
727
+ // see: musl/src/math/cbrt.c and SUN COPYRIGHT NOTICE above
728
+ const B1 = <u32>715094163,
729
+ B2 = <u32>696219795,
730
+ P0 = reinterpret<f64>(0x3ffe03e60f61e692), // 1.87595182427177009643
731
+ P1 = reinterpret<f64>(0xbffe28e092f02420), // -1.88497979543377169875
732
+ P2 = reinterpret<f64>(0x3ff9f1604a49d6c2), // 1.621429720105354466140
733
+ P3 = reinterpret<f64>(0xbfe844cbbee751d9), // -0.758397934778766047437
734
+ P4 = reinterpret<f64>(0x3fc2b000d4e4edd7), // 0.145996192886612446982
735
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 0x1p54
736
+
737
+ let u = reinterpret<u64>(x);
738
+ let hx = (<u32>(u >> 32)) & 0x7fffffff;
739
+ if (hx >= 0x7ff00000) return x + x;
740
+ if (hx < 0x00100000) {
741
+ u = reinterpret<u64>(x * Ox1p54);
742
+ hx = (<u32>(u >> 32)) & 0x7fffffff;
743
+ if (hx == 0) return x;
744
+ hx = hx / 3 + B2;
745
+ } else {
746
+ hx = hx / 3 + B1;
747
+ }
748
+ u &= 1 << 63;
749
+ u |= (<u64>hx) << 32;
750
+ let t = reinterpret<f64>(u);
751
+ let r = t * t * (t / x);
752
+ t = t * (P0 + r * (P1 + r * P2) + r * r * r * (P3 + r * P4));
753
+ t = reinterpret<f64>((reinterpret<u64>(t) + 0x80000000) & 0xffffffffc0000000);
754
+ let s = t * t;
755
+ r = x / s;
756
+ r = (r - t) / (2 * t + r);
757
+ t = t + t * r;
758
+ return t;
759
+ }
760
+
761
+ // @ts-ignore: decorator
762
+ @inline
763
+ export function ceil(x: f64): f64 {
764
+ return builtin_ceil<f64>(x);
765
+ }
766
+
767
+ export function clz32(x: f64): f64 {
768
+ if (!isFinite(x)) return 32;
769
+ /*
770
+ * Wasm (MVP) and JS have different approaches for double->int conversions.
771
+ *
772
+ * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
773
+ * our float-point arguments before actual convertion to integers.
774
+ */
775
+ return builtin_clz(dtoi32(x));
776
+ }
777
+
778
+ export function cos(x: f64): f64 {
779
+ // see: musl/src/math/cos.c
780
+ let u = reinterpret<u64>(x);
781
+ let ux = u32(u >> 32);
782
+ let sign = ux >> 31;
783
+
784
+ ux &= 0x7fffffff;
785
+
786
+ // |x| ~< pi/4
787
+ if (ux <= 0x3fe921fb) {
788
+ if (ux < 0x3e46a09e) {
789
+ // |x| < 2**-27 * sqrt(2)
790
+ return 1.0;
791
+ }
792
+ return cos_kern(x, 0);
793
+ }
794
+
795
+ // sin(Inf or NaN) is NaN
796
+ if (ux >= 0x7ff00000) return x - x;
797
+
798
+ // argument reduction needed
799
+ let n = rempio2(x, u, sign);
800
+ let y0 = rempio2_y0;
801
+ let y1 = rempio2_y1;
802
+
803
+ x = n & 1 ? sin_kern(y0, y1, 1) : cos_kern(y0, y1);
804
+ return (n + 1) & 2 ? -x : x;
805
+ }
806
+
807
+ export function cosh(x: f64): f64 {
808
+ // see: musl/src/math/cosh.c
809
+ let u = reinterpret<u64>(x);
810
+ u &= 0x7fffffffffffffff;
811
+ x = reinterpret<f64>(u);
812
+ let w = <u32>(u >> 32);
813
+ let t: f64;
814
+ if (w < 0x3fe62e42) {
815
+ if (w < 0x3ff00000 - (26 << 20)) return 1;
816
+ t = expm1(x);
817
+ // return 1 + t * t / (2 * (1 + t));
818
+ return 1 + (t * t) / (2 + 2 * t);
819
+ }
820
+ if (w < 0x40862e42) {
821
+ t = exp(x);
822
+ return 0.5 * (t + 1 / t);
823
+ }
824
+ t = expo2(x, 1);
825
+ return t;
826
+ }
827
+
828
+ export function exp(x: f64): f64 {
829
+ // see: musl/src/math/exp.c and SUN COPYRIGHT NOTICE above
830
+ if (ASC_SHRINK_LEVEL < 1) {
831
+ return exp_lut(x);
832
+ } else {
833
+ const ln2hi = reinterpret<f64>(0x3fe62e42fee00000), // 6.93147180369123816490e-01
834
+ ln2lo = reinterpret<f64>(0x3dea39ef35793c76), // 1.90821492927058770002e-10
835
+ invln2 = reinterpret<f64>(0x3ff71547652b82fe), // 1.44269504088896338700e+00
836
+ P1 = reinterpret<f64>(0x3fc555555555553e), // 1.66666666666666019037e-01
837
+ P2 = reinterpret<f64>(0xbf66c16c16bebd93), // -2.77777777770155933842e-03
838
+ P3 = reinterpret<f64>(0x3f11566aaf25de2c), // 6.61375632143793436117e-05
839
+ P4 = reinterpret<f64>(0xbebbbd41c5d26bf1), // -1.65339022054652515390e-06
840
+ P5 = reinterpret<f64>(0x3e66376972bea4d0), // 4.13813679705723846039e-08
841
+ overflow = reinterpret<f64>(0x40862e42fefa39ef), // 709.782712893383973096
842
+ underflow = reinterpret<f64>(0xc0874910d52d3051), // -745.13321910194110842
843
+ Ox1p1023 = reinterpret<f64>(0x7fe0000000000000); // 0x1p1023
844
+
845
+ let hx = u32(reinterpret<u64>(x) >> 32);
846
+ let sign = hx >> 31;
847
+ hx &= 0x7fffffff;
848
+ if (hx >= 0x4086232b) {
849
+ if (isNaN(x)) return x;
850
+ if (x > overflow) return x * Ox1p1023;
851
+ if (x < underflow) return 0;
852
+ }
853
+ let hi: f64,
854
+ lo: f64 = 0;
855
+ let k = 0;
856
+ if (hx > 0x3fd62e42) {
857
+ if (hx >= 0x3ff0a2b2) {
858
+ k = i32(invln2 * x + builtin_copysign<f64>(0.5, x));
859
+ } else {
860
+ k = 1 - (sign << 1);
861
+ }
862
+ hi = x - k * ln2hi;
863
+ lo = k * ln2lo;
864
+ x = hi - lo;
865
+ } else if (hx > 0x3e300000) {
866
+ hi = x;
867
+ } else return 1.0 + x;
868
+ let xs = x * x;
869
+ // let c = x - xp2 * (P1 + xp2 * (P2 + xp2 * (P3 + xp2 * (P4 + xp2 * P5))));
870
+ let xq = xs * xs;
871
+ let c = x - (xs * P1 + xq * (P2 + xs * P3 + xq * (P4 + xs * P5)));
872
+ let y = 1.0 + ((x * c) / (2 - c) - lo + hi);
873
+ return k == 0 ? y : scalbn(y, k);
874
+ }
875
+ }
876
+
877
+ export function exp2(x: f64): f64 {
878
+ return exp2_lut(x);
879
+ }
880
+
881
+ export function expm1(x: f64): f64 {
882
+ // see: musl/src/math/expm1.c and SUN COPYRIGHT NOTICE above
883
+ const o_threshold = reinterpret<f64>(0x40862e42fefa39ef), // 7.09782712893383973096e+02
884
+ ln2_hi = reinterpret<f64>(0x3fe62e42fee00000), // 6.93147180369123816490e-01
885
+ ln2_lo = reinterpret<f64>(0x3dea39ef35793c76), // 1.90821492927058770002e-10
886
+ invln2 = reinterpret<f64>(0x3ff71547652b82fe), // 1.44269504088896338700e+00
887
+ Q1 = reinterpret<f64>(0xbfa11111111110f4), // -3.33333333333331316428e-02
888
+ Q2 = reinterpret<f64>(0x3f5a01a019fe5585), // 1.58730158725481460165e-03
889
+ Q3 = reinterpret<f64>(0xbf14ce199eaadbb7), // -7.93650757867487942473e-05
890
+ Q4 = reinterpret<f64>(0x3ed0cfca86e65239), // 4.00821782732936239552e-06
891
+ Q5 = reinterpret<f64>(0xbe8afdb76e09c32d), // -2.01099218183624371326e-07
892
+ Ox1p1023 = reinterpret<f64>(0x7fe0000000000000); // 0x1p1023
893
+
894
+ let u = reinterpret<u64>(x);
895
+ let hx = u32(u >> 32) & 0x7fffffff;
896
+ let sign = u32(u >> 63);
897
+ let k = 0;
898
+ if (hx >= 0x4043687a) {
899
+ if (isNaN(x)) return x;
900
+ if (sign) return -1;
901
+ if (x > o_threshold) return x * Ox1p1023;
902
+ }
903
+ let c = 0.0,
904
+ t: f64;
905
+ if (hx > 0x3fd62e42) {
906
+ k = select<i32>(1 - (sign << 1), i32(invln2 * x + builtin_copysign<f64>(0.5, x)), hx < 0x3ff0a2b2);
907
+ t = <f64>k;
908
+ let hi = x - t * ln2_hi;
909
+ let lo = t * ln2_lo;
910
+ x = hi - lo;
911
+ c = hi - x - lo;
912
+ } else if (hx < 0x3c900000) return x;
913
+ let hfx = 0.5 * x;
914
+ let hxs = x * hfx;
915
+ // let r1 = 1.0 + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
916
+ let hxq = hxs * hxs;
917
+ let r1 = 1.0 + hxs * Q1 + hxq * (Q2 + hxs * Q3 + hxq * (Q4 + hxs * Q5));
918
+ t = 3.0 - r1 * hfx;
919
+ let e = hxs * ((r1 - t) / (6.0 - x * t));
920
+ if (k == 0) return x - (x * e - hxs);
921
+ e = x * (e - c) - c;
922
+ e -= hxs;
923
+ if (k == -1) return 0.5 * (x - e) - 0.5;
924
+ if (k == 1) {
925
+ if (x < -0.25) return -2.0 * (e - (x + 0.5));
926
+ return 1.0 + 2.0 * (x - e);
927
+ }
928
+ u = (0x3ff + k) << 52;
929
+ let twopk = reinterpret<f64>(u);
930
+ let y: f64;
931
+ if (k < 0 || k > 56) {
932
+ y = x - e + 1.0;
933
+ if (k == 1024) y = y * 2.0 * Ox1p1023;
934
+ else y = y * twopk;
935
+ return y - 1.0;
936
+ }
937
+ u = (0x3ff - k) << 52;
938
+ y = reinterpret<f64>(u);
939
+ if (k < 20) y = 1 - y - e;
940
+ else y = 1 - (e + y);
941
+ return (x + y) * twopk;
942
+ }
943
+
944
+ // @ts-ignore: decorator
945
+ @inline
946
+ export function floor(x: f64): f64 {
947
+ return builtin_floor<f64>(x);
948
+ }
949
+
950
+ // @ts-ignore: decorator
951
+ @inline
952
+ export function fround(x: f64): f64 {
953
+ return <f32>x;
954
+ }
955
+
956
+ export function hypot(x: f64, y: f64): f64 {
957
+ // see: musl/src/math/hypot.c
958
+ const SPLIT = reinterpret<f64>(0x41a0000000000000) + 1, // 0x1p27 + 1
959
+ Ox1p700 = reinterpret<f64>(0x6bb0000000000000),
960
+ Ox1p_700 = reinterpret<f64>(0x1430000000000000);
961
+
962
+ let ux = reinterpret<u64>(x);
963
+ let uy = reinterpret<u64>(y);
964
+ ux &= 0x7fffffffffffffff;
965
+ uy &= 0x7fffffffffffffff;
966
+ if (ux < uy) {
967
+ let ut = ux;
968
+ ux = uy;
969
+ uy = ut;
970
+ }
971
+ let ex = i32(ux >> 52);
972
+ let ey = i32(uy >> 52);
973
+ y = reinterpret<f64>(uy);
974
+ if (ey == 0x7ff) return y;
975
+ x = reinterpret<f64>(ux);
976
+ if (ex == 0x7ff || uy == 0) return x;
977
+ if (ex - ey > 64) return x + y;
978
+ let z = 1.0;
979
+ if (ex > 0x3ff + 510) {
980
+ z = Ox1p700;
981
+ x *= Ox1p_700;
982
+ y *= Ox1p_700;
983
+ } else if (ey < 0x3ff - 450) {
984
+ z = Ox1p_700;
985
+ x *= Ox1p700;
986
+ y *= Ox1p700;
987
+ }
988
+ let c = x * SPLIT;
989
+ let h = x - c + c;
990
+ let l = x - h;
991
+ let hx = x * x;
992
+ let lx = h * h - hx + (2 * h + l) * l;
993
+ c = y * SPLIT;
994
+ h = y - c + c;
995
+ l = y - h;
996
+ let hy = y * y;
997
+ let ly = h * h - hy + (2 * h + l) * l;
998
+ return z * builtin_sqrt(ly + lx + hy + hx);
999
+ }
1000
+
1001
+ export function imul(x: f64, y: f64): f64 {
1002
+ /*
1003
+ * Wasm (MVP) and JS have different approaches for double->int conversions.
1004
+ *
1005
+ * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
1006
+ * our float-point arguments before actual convertion to integers.
1007
+ */
1008
+ if (!isFinite(x + y)) return 0;
1009
+ return dtoi32(x) * dtoi32(y);
1010
+ }
1011
+
1012
+ export function log(x: f64): f64 {
1013
+ // see: musl/src/math/log.c and SUN COPYRIGHT NOTICE above
1014
+ if (ASC_SHRINK_LEVEL < 1) {
1015
+ return log_lut(x);
1016
+ } else {
1017
+ const ln2_hi = reinterpret<f64>(0x3fe62e42fee00000), // 6.93147180369123816490e-01
1018
+ ln2_lo = reinterpret<f64>(0x3dea39ef35793c76), // 1.90821492927058770002e-10
1019
+ Lg1 = reinterpret<f64>(0x3fe5555555555593), // 6.666666666666735130e-01
1020
+ Lg2 = reinterpret<f64>(0x3fd999999997fa04), // 3.999999999940941908e-01
1021
+ Lg3 = reinterpret<f64>(0x3fd2492494229359), // 2.857142874366239149e-01
1022
+ Lg4 = reinterpret<f64>(0x3fcc71c51d8e78af), // 2.222219843214978396e-01
1023
+ Lg5 = reinterpret<f64>(0x3fc7466496cb03de), // 1.818357216161805012e-01
1024
+ Lg6 = reinterpret<f64>(0x3fc39a09d078c69f), // 1.531383769920937332e-01
1025
+ Lg7 = reinterpret<f64>(0x3fc2f112df3e5244), // 1.479819860511658591e-01
1026
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 0x1p54
1027
+
1028
+ let u = reinterpret<u64>(x);
1029
+ let hx = u32(u >> 32);
1030
+ let k = 0;
1031
+ let sign = hx >> 31;
1032
+ if (sign || hx < 0x00100000) {
1033
+ if (u << 1 == 0) return -1 / (x * x);
1034
+ if (sign) return (x - x) / 0.0;
1035
+ k -= 54;
1036
+ x *= Ox1p54;
1037
+ u = reinterpret<u64>(x);
1038
+ hx = u32(u >> 32);
1039
+ } else if (hx >= 0x7ff00000) {
1040
+ return x;
1041
+ } else if (hx == 0x3ff00000 && u << 32 == 0) {
1042
+ return 0;
1043
+ }
1044
+ hx += 0x3ff00000 - 0x3fe6a09e;
1045
+ k += ((<i32>hx) >> 20) - 0x3ff;
1046
+ hx = (hx & 0x000fffff) + 0x3fe6a09e;
1047
+ u = ((<u64>hx) << 32) | (u & 0xffffffff);
1048
+ x = reinterpret<f64>(u);
1049
+ let f = x - 1.0;
1050
+ let hfsq = 0.5 * f * f;
1051
+ let s = f / (2.0 + f);
1052
+ let z = s * s;
1053
+ let w = z * z;
1054
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1055
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1056
+ let r = t2 + t1;
1057
+ let dk = <f64>k;
1058
+ return s * (hfsq + r) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
1059
+ }
1060
+ }
1061
+
1062
+ export function log10(x: f64): f64 {
1063
+ // see: musl/src/math/log10.c and SUN COPYRIGHT NOTICE above
1064
+ const ivln10hi = reinterpret<f64>(0x3fdbcb7b15200000), // 4.34294481878168880939e-01
1065
+ ivln10lo = reinterpret<f64>(0x3dbb9438ca9aadd5), // 2.50829467116452752298e-11
1066
+ log10_2hi = reinterpret<f64>(0x3fd34413509f6000), // 3.01029995663611771306e-01
1067
+ log10_2lo = reinterpret<f64>(0x3d59fef311f12b36), // 3.69423907715893078616e-13
1068
+ Lg1 = reinterpret<f64>(0x3fe5555555555593), // 6.666666666666735130e-01
1069
+ Lg2 = reinterpret<f64>(0x3fd999999997fa04), // 3.999999999940941908e-01
1070
+ Lg3 = reinterpret<f64>(0x3fd2492494229359), // 2.857142874366239149e-01
1071
+ Lg4 = reinterpret<f64>(0x3fcc71c51d8e78af), // 2.222219843214978396e-01
1072
+ Lg5 = reinterpret<f64>(0x3fc7466496cb03de), // 1.818357216161805012e-01
1073
+ Lg6 = reinterpret<f64>(0x3fc39a09d078c69f), // 1.531383769920937332e-01
1074
+ Lg7 = reinterpret<f64>(0x3fc2f112df3e5244), // 1.479819860511658591e-01
1075
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 0x1p54
1076
+
1077
+ let u = reinterpret<u64>(x);
1078
+ let hx = u32(u >> 32);
1079
+ let k = 0;
1080
+ let sign = hx >> 31;
1081
+ if (sign || hx < 0x00100000) {
1082
+ if (u << 1 == 0) return -1 / (x * x);
1083
+ if (sign) return (x - x) / 0.0;
1084
+ k -= 54;
1085
+ x *= Ox1p54;
1086
+ u = reinterpret<u64>(x);
1087
+ hx = u32(u >> 32);
1088
+ } else if (hx >= 0x7ff00000) {
1089
+ return x;
1090
+ } else if (hx == 0x3ff00000 && u << 32 == 0) {
1091
+ return 0;
1092
+ }
1093
+ hx += 0x3ff00000 - 0x3fe6a09e;
1094
+ k += i32(hx >> 20) - 0x3ff;
1095
+ hx = (hx & 0x000fffff) + 0x3fe6a09e;
1096
+ u = ((<u64>hx) << 32) | (u & 0xffffffff);
1097
+ x = reinterpret<f64>(u);
1098
+ let f = x - 1.0;
1099
+ let hfsq = 0.5 * f * f;
1100
+ let s = f / (2.0 + f);
1101
+ let z = s * s;
1102
+ let w = z * z;
1103
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1104
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1105
+ let r = t2 + t1;
1106
+ let hi = f - hfsq;
1107
+ u = reinterpret<u64>(hi);
1108
+ u &= 0xffffffff00000000;
1109
+ hi = reinterpret<f64>(u);
1110
+ let lo = f - hi - hfsq + s * (hfsq + r);
1111
+ let val_hi = hi * ivln10hi;
1112
+ let dk = <f64>k;
1113
+ let y = dk * log10_2hi;
1114
+ let val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi;
1115
+ w = y + val_hi;
1116
+ val_lo += y - w + val_hi;
1117
+ return val_lo + w;
1118
+ }
1119
+
1120
+ export function log1p(x: f64): f64 {
1121
+ // see: musl/src/math/log1p.c and SUN COPYRIGHT NOTICE above
1122
+ const ln2_hi = reinterpret<f64>(0x3fe62e42fee00000), // 6.93147180369123816490e-01
1123
+ ln2_lo = reinterpret<f64>(0x3dea39ef35793c76), // 1.90821492927058770002e-10
1124
+ Lg1 = reinterpret<f64>(0x3fe5555555555593), // 6.666666666666735130e-01
1125
+ Lg2 = reinterpret<f64>(0x3fd999999997fa04), // 3.999999999940941908e-01
1126
+ Lg3 = reinterpret<f64>(0x3fd2492494229359), // 2.857142874366239149e-01
1127
+ Lg4 = reinterpret<f64>(0x3fcc71c51d8e78af), // 2.222219843214978396e-01
1128
+ Lg5 = reinterpret<f64>(0x3fc7466496cb03de), // 1.818357216161805012e-01
1129
+ Lg6 = reinterpret<f64>(0x3fc39a09d078c69f), // 1.531383769920937332e-01
1130
+ Lg7 = reinterpret<f64>(0x3fc2f112df3e5244); // 1.479819860511658591e-01
1131
+
1132
+ let u = reinterpret<u64>(x);
1133
+ let hx = u32(u >> 32);
1134
+ let k = 1;
1135
+ let c = 0.0,
1136
+ f = 0.0;
1137
+ if (hx < 0x3fda827a || bool(hx >> 31)) {
1138
+ if (hx >= 0xbff00000) {
1139
+ if (x == -1) return x / 0.0;
1140
+ return (x - x) / 0.0;
1141
+ }
1142
+ if (hx << 1 < 0x3ca00000 << 1) return x;
1143
+ if (hx <= 0xbfd2bec4) {
1144
+ k = 0;
1145
+ c = 0;
1146
+ f = x;
1147
+ }
1148
+ } else if (hx >= 0x7ff00000) return x;
1149
+ if (k) {
1150
+ u = reinterpret<u64>(1 + x);
1151
+ let hu = u32(u >> 32);
1152
+ hu += 0x3ff00000 - 0x3fe6a09e;
1153
+ k = i32(hu >> 20) - 0x3ff;
1154
+ if (k < 54) {
1155
+ let uf = reinterpret<f64>(u);
1156
+ c = k >= 2 ? 1 - (uf - x) : x - (uf - 1);
1157
+ c /= uf;
1158
+ } else c = 0;
1159
+ hu = (hu & 0x000fffff) + 0x3fe6a09e;
1160
+ u = ((<u64>hu) << 32) | (u & 0xffffffff);
1161
+ f = reinterpret<f64>(u) - 1;
1162
+ }
1163
+ let hfsq = 0.5 * f * f;
1164
+ let s = f / (2.0 + f);
1165
+ let z = s * s;
1166
+ let w = z * z;
1167
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1168
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1169
+ let r = t2 + t1;
1170
+ let dk = <f64>k;
1171
+ return s * (hfsq + r) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
1172
+ }
1173
+
1174
+ export function log2(x: f64): f64 {
1175
+ // see: musl/src/math/log2.c and SUN COPYRIGHT NOTICE above
1176
+ if (ASC_SHRINK_LEVEL < 1) {
1177
+ return log2_lut(x);
1178
+ } else {
1179
+ const ivln2hi = reinterpret<f64>(0x3ff7154765200000), // 1.44269504072144627571e+00
1180
+ ivln2lo = reinterpret<f64>(0x3de705fc2eefa200), // 1.67517131648865118353e-10
1181
+ Lg1 = reinterpret<f64>(0x3fe5555555555593), // 6.666666666666735130e-01
1182
+ Lg2 = reinterpret<f64>(0x3fd999999997fa04), // 3.999999999940941908e-01
1183
+ Lg3 = reinterpret<f64>(0x3fd2492494229359), // 2.857142874366239149e-01
1184
+ Lg4 = reinterpret<f64>(0x3fcc71c51d8e78af), // 2.222219843214978396e-01
1185
+ Lg5 = reinterpret<f64>(0x3fc7466496cb03de), // 1.818357216161805012e-01
1186
+ Lg6 = reinterpret<f64>(0x3fc39a09d078c69f), // 1.531383769920937332e-01
1187
+ Lg7 = reinterpret<f64>(0x3fc2f112df3e5244), // 1.479819860511658591e-01
1188
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 1p54
1189
+
1190
+ let u = reinterpret<u64>(x);
1191
+ let hx = u32(u >> 32);
1192
+ let k = 0;
1193
+ let sign = hx >> 31;
1194
+ if (sign || hx < 0x00100000) {
1195
+ if (u << 1 == 0) return -1 / (x * x);
1196
+ if (sign) return (x - x) / 0.0;
1197
+ k -= 54;
1198
+ x *= Ox1p54;
1199
+ u = reinterpret<u64>(x);
1200
+ hx = u32(u >> 32);
1201
+ } else if (hx >= 0x7ff00000) {
1202
+ return x;
1203
+ } else if (hx == 0x3ff00000 && u << 32 == 0) {
1204
+ return 0;
1205
+ }
1206
+ hx += 0x3ff00000 - 0x3fe6a09e;
1207
+ k += i32(hx >> 20) - 0x3ff;
1208
+ hx = (hx & 0x000fffff) + 0x3fe6a09e;
1209
+ u = ((<u64>hx) << 32) | (u & 0xffffffff);
1210
+ x = reinterpret<f64>(u);
1211
+ let f = x - 1.0;
1212
+ let hfsq = 0.5 * f * f;
1213
+ let s = f / (2.0 + f);
1214
+ let z = s * s;
1215
+ let w = z * z;
1216
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1217
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1218
+ let r = t2 + t1;
1219
+ let hi = f - hfsq;
1220
+ u = reinterpret<u64>(hi);
1221
+ u &= 0xffffffff00000000;
1222
+ hi = reinterpret<f64>(u);
1223
+ let lo = f - hi - hfsq + s * (hfsq + r);
1224
+ let val_hi = hi * ivln2hi;
1225
+ let val_lo = (lo + hi) * ivln2lo + lo * ivln2hi;
1226
+ let y = <f64>k;
1227
+ w = y + val_hi;
1228
+ val_lo += y - w + val_hi;
1229
+ val_hi = w;
1230
+ return val_lo + val_hi;
1231
+ }
1232
+ }
1233
+
1234
+ // @ts-ignore: decorator
1235
+ @inline
1236
+ export function max(value1: f64, value2: f64): f64 {
1237
+ return builtin_max<f64>(value1, value2);
1238
+ }
1239
+
1240
+ // @ts-ignore: decorator
1241
+ @inline
1242
+ export function min(value1: f64, value2: f64): f64 {
1243
+ return builtin_min<f64>(value1, value2);
1244
+ }
1245
+
1246
+ export function pow(x: f64, y: f64): f64 {
1247
+ // see: musl/src/math/pow.c and SUN COPYRIGHT NOTICE above
1248
+ // TODO: remove this fast pathes after introduced own mid-end IR with "stdlib call simplify" transforms
1249
+ if (builtin_abs<f64>(y) <= 2) {
1250
+ if (y == 2.0) return x * x;
1251
+ if (y == 0.5) {
1252
+ return select<f64>(builtin_abs<f64>(builtin_sqrt<f64>(x)), Infinity, x != -Infinity);
1253
+ }
1254
+ if (y == -1.0) return 1 / x;
1255
+ if (y == 1.0) return x;
1256
+ if (y == 0.0) return 1.0;
1257
+ }
1258
+ if (ASC_SHRINK_LEVEL < 1) {
1259
+ return pow_lut(x, y);
1260
+ } else {
1261
+ const dp_h1 = reinterpret<f64>(0x3fe2b80340000000), // 5.84962487220764160156e-01
1262
+ dp_l1 = reinterpret<f64>(0x3e4cfdeb43cfd006), // 1.35003920212974897128e-08
1263
+ two53 = reinterpret<f64>(0x4340000000000000), // 9007199254740992.0
1264
+ huge = reinterpret<f64>(0x7e37e43c8800759c), // 1e+300
1265
+ tiny = reinterpret<f64>(0x01a56e1fc2f8f359), // 1e-300
1266
+ L1 = reinterpret<f64>(0x3fe3333333333303), // 5.99999999999994648725e-01
1267
+ L2 = reinterpret<f64>(0x3fdb6db6db6fabff), // 4.28571428578550184252e-01
1268
+ L3 = reinterpret<f64>(0x3fd55555518f264d), // 3.33333329818377432918e-01
1269
+ L4 = reinterpret<f64>(0x3fd17460a91d4101), // 2.72728123808534006489e-01
1270
+ L5 = reinterpret<f64>(0x3fcd864a93c9db65), // 2.30660745775561754067e-01
1271
+ L6 = reinterpret<f64>(0x3fca7e284a454eef), // 2.06975017800338417784e-01
1272
+ P1 = reinterpret<f64>(0x3fc555555555553e), // 1.66666666666666019037e-01
1273
+ P2 = reinterpret<f64>(0xbf66c16c16bebd93), // -2.77777777770155933842e-03
1274
+ P3 = reinterpret<f64>(0x3f11566aaf25de2c), // 6.61375632143793436117e-05
1275
+ P4 = reinterpret<f64>(0xbebbbd41c5d26bf1), // -1.65339022054652515390e-06
1276
+ P5 = reinterpret<f64>(0x3e66376972bea4d0), // 4.13813679705723846039e-08
1277
+ lg2 = reinterpret<f64>(0x3fe62e42fefa39ef), // 6.93147180559945286227e-01
1278
+ lg2_h = reinterpret<f64>(0x3fe62e4300000000), // 6.93147182464599609375e-01
1279
+ lg2_l = reinterpret<f64>(0xbe205c610ca86c39), // -1.90465429995776804525e-09
1280
+ ovt = reinterpret<f64>(0x3c971547652b82fe), // 8.0085662595372944372e-017
1281
+ cp = reinterpret<f64>(0x3feec709dc3a03fd), // 9.61796693925975554329e-01
1282
+ cp_h = reinterpret<f64>(0x3feec709e0000000), // 9.61796700954437255859e-01
1283
+ cp_l = reinterpret<f64>(0xbe3e2fe0145b01f5), // -7.02846165095275826516e-09
1284
+ ivln2 = reinterpret<f64>(0x3ff71547652b82fe), // 1.44269504088896338700e+00
1285
+ ivln2_h = reinterpret<f64>(0x3ff7154760000000), // 1.44269502162933349609e+00
1286
+ ivln2_l = reinterpret<f64>(0x3e54ae0bf85ddf44), // 1.92596299112661746887e-08
1287
+ inv3 = reinterpret<f64>(0x3fd5555555555555); // 0.3333333333333333333333
1288
+
1289
+ let u_ = reinterpret<u64>(x);
1290
+ let hx = i32(u_ >> 32);
1291
+ let lx = <u32>u_;
1292
+ u_ = reinterpret<u64>(y);
1293
+ let hy = i32(u_ >> 32);
1294
+ let ly = <u32>u_;
1295
+ let ix = hx & 0x7fffffff;
1296
+ let iy = hy & 0x7fffffff;
1297
+ if ((iy | ly) == 0) return 1.0; // x**0 = 1, even if x is NaN
1298
+ // if (hx == 0x3FF00000 && lx == 0) return 1.0; // C: 1**y = 1, even if y is NaN, JS: NaN
1299
+ if (
1300
+ // NaN if either arg is NaN
1301
+ ix > 0x7ff00000 ||
1302
+ (ix == 0x7ff00000 && lx != 0) ||
1303
+ iy > 0x7ff00000 ||
1304
+ (iy == 0x7ff00000 && ly != 0)
1305
+ )
1306
+ return x + y;
1307
+ let yisint = 0,
1308
+ k: i32;
1309
+ if (hx < 0) {
1310
+ if (iy >= 0x43400000) yisint = 2;
1311
+ else if (iy >= 0x3ff00000) {
1312
+ k = (iy >> 20) - 0x3ff;
1313
+ let offset = select<u32>(52, 20, k > 20) - k;
1314
+ let Ly = select<u32>(ly, iy, k > 20);
1315
+ let jj = Ly >> offset;
1316
+ if (jj << offset == Ly) yisint = 2 - (jj & 1);
1317
+ }
1318
+ }
1319
+ if (ly == 0) {
1320
+ if (iy == 0x7ff00000) {
1321
+ // y is +-inf
1322
+ if (((ix - 0x3ff00000) | lx) == 0)
1323
+ return NaN; // C: (-1)**+-inf is 1, JS: NaN
1324
+ else if (ix >= 0x3ff00000)
1325
+ return hy >= 0 ? y : 0.0; // (|x|>1)**+-inf = inf,0
1326
+ else return hy >= 0 ? 0.0 : -y; // (|x|<1)**+-inf = 0,inf
1327
+ }
1328
+ if (iy == 0x3ff00000) {
1329
+ if (hy >= 0) return x;
1330
+ return 1 / x;
1331
+ }
1332
+ if (hy == 0x40000000) return x * x;
1333
+ if (hy == 0x3fe00000) {
1334
+ if (hx >= 0) return builtin_sqrt(x);
1335
+ }
1336
+ }
1337
+ let ax = builtin_abs<f64>(x),
1338
+ z: f64;
1339
+ if (lx == 0) {
1340
+ if (ix == 0 || ix == 0x7ff00000 || ix == 0x3ff00000) {
1341
+ z = ax;
1342
+ if (hy < 0) z = 1.0 / z;
1343
+ if (hx < 0) {
1344
+ if (((ix - 0x3ff00000) | yisint) == 0) {
1345
+ let d = z - z;
1346
+ z = d / d;
1347
+ } else if (yisint == 1) z = -z;
1348
+ }
1349
+ return z;
1350
+ }
1351
+ }
1352
+ let s = 1.0;
1353
+ if (hx < 0) {
1354
+ if (yisint == 0) {
1355
+ let d = x - x;
1356
+ return d / d;
1357
+ }
1358
+ if (yisint == 1) s = -1.0;
1359
+ }
1360
+ let t1: f64, t2: f64, p_h: f64, p_l: f64, r: f64, t: f64, u: f64, v: f64, w: f64;
1361
+ let j: i32, n: i32;
1362
+ if (iy > 0x41e00000) {
1363
+ if (iy > 0x43f00000) {
1364
+ if (ix <= 0x3fefffff) return hy < 0 ? huge * huge : tiny * tiny;
1365
+ if (ix >= 0x3ff00000) return hy > 0 ? huge * huge : tiny * tiny;
1366
+ }
1367
+ if (ix < 0x3fefffff) return hy < 0 ? s * huge * huge : s * tiny * tiny;
1368
+ if (ix > 0x3ff00000) return hy > 0 ? s * huge * huge : s * tiny * tiny;
1369
+ t = ax - 1.0;
1370
+ w = t * t * (0.5 - t * (inv3 - t * 0.25));
1371
+ u = ivln2_h * t;
1372
+ v = t * ivln2_l - w * ivln2;
1373
+ t1 = u + v;
1374
+ t1 = reinterpret<f64>(reinterpret<u64>(t1) & 0xffffffff00000000);
1375
+ t2 = v - (t1 - u);
1376
+ } else {
1377
+ let ss: f64, s2: f64, s_h: f64, s_l: f64, t_h: f64, t_l: f64;
1378
+ n = 0;
1379
+ if (ix < 0x00100000) {
1380
+ ax *= two53;
1381
+ n -= 53;
1382
+ ix = <u32>(reinterpret<u64>(ax) >> 32);
1383
+ }
1384
+ n += (ix >> 20) - 0x3ff;
1385
+ j = ix & 0x000fffff;
1386
+ ix = j | 0x3ff00000;
1387
+ if (j <= 0x3988e) k = 0;
1388
+ else if (j < 0xbb67a) k = 1;
1389
+ else {
1390
+ k = 0;
1391
+ n += 1;
1392
+ ix -= 0x00100000;
1393
+ }
1394
+ ax = reinterpret<f64>((reinterpret<u64>(ax) & 0xffffffff) | ((<u64>ix) << 32));
1395
+ let bp = select<f64>(1.5, 1.0, k); // k ? 1.5 : 1.0
1396
+ u = ax - bp;
1397
+ v = 1.0 / (ax + bp);
1398
+ ss = u * v;
1399
+ s_h = ss;
1400
+ s_h = reinterpret<f64>(reinterpret<u64>(s_h) & 0xffffffff00000000);
1401
+ t_h = reinterpret<f64>(u64(((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18)) << 32);
1402
+ t_l = ax - (t_h - bp);
1403
+ s_l = v * (u - s_h * t_h - s_h * t_l);
1404
+ s2 = ss * ss;
1405
+ r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6)))));
1406
+ r += s_l * (s_h + ss);
1407
+ s2 = s_h * s_h;
1408
+ t_h = 3.0 + s2 + r;
1409
+ t_h = reinterpret<f64>(reinterpret<u64>(t_h) & 0xffffffff00000000);
1410
+ t_l = r - (t_h - 3.0 - s2);
1411
+ u = s_h * t_h;
1412
+ v = s_l * t_h + t_l * ss;
1413
+ p_h = u + v;
1414
+ p_h = reinterpret<f64>(reinterpret<u64>(p_h) & 0xffffffff00000000);
1415
+ p_l = v - (p_h - u);
1416
+ let z_h = cp_h * p_h;
1417
+ let dp_l = select<f64>(dp_l1, 0.0, k);
1418
+ let z_l = cp_l * p_h + p_l * cp + dp_l;
1419
+ t = <f64>n;
1420
+ let dp_h = select<f64>(dp_h1, 0.0, k);
1421
+ t1 = z_h + z_l + dp_h + t;
1422
+ t1 = reinterpret<f64>(reinterpret<u64>(t1) & 0xffffffff00000000);
1423
+ t2 = z_l - (t1 - t - dp_h - z_h);
1424
+ }
1425
+ let y1 = y;
1426
+ y1 = reinterpret<f64>(reinterpret<u64>(y1) & 0xffffffff00000000);
1427
+ p_l = (y - y1) * t1 + y * t2;
1428
+ p_h = y1 * t1;
1429
+ z = p_l + p_h;
1430
+ u_ = reinterpret<u64>(z);
1431
+ j = u32(u_ >> 32);
1432
+ let i = <i32>u_;
1433
+ if (j >= 0x40900000) {
1434
+ if (((j - 0x40900000) | i) != 0) return s * huge * huge;
1435
+ if (p_l + ovt > z - p_h) return s * huge * huge;
1436
+ } else if ((j & 0x7fffffff) >= 0x4090cc00) {
1437
+ if (((j - 0xc090cc00) | i) != 0) return s * tiny * tiny;
1438
+ if (p_l <= z - p_h) return s * tiny * tiny;
1439
+ }
1440
+ i = j & 0x7fffffff;
1441
+ k = (i >> 20) - 0x3ff;
1442
+ n = 0;
1443
+ if (i > 0x3fe00000) {
1444
+ n = j + (0x00100000 >> (k + 1));
1445
+ k = ((n & 0x7fffffff) >> 20) - 0x3ff;
1446
+ t = 0.0;
1447
+ t = reinterpret<f64>(u64(n & ~(0x000fffff >> k)) << 32);
1448
+ n = ((n & 0x000fffff) | 0x00100000) >> (20 - k);
1449
+ if (j < 0) n = -n;
1450
+ p_h -= t;
1451
+ }
1452
+ t = p_l + p_h;
1453
+ t = reinterpret<f64>(reinterpret<u64>(t) & 0xffffffff00000000);
1454
+ u = t * lg2_h;
1455
+ v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
1456
+ z = u + v;
1457
+ w = v - (z - u);
1458
+ t = z * z;
1459
+ t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
1460
+ r = (z * t1) / (t1 - 2.0) - (w + z * w);
1461
+ z = 1.0 - (r - z);
1462
+ j = u32(reinterpret<u64>(z) >> 32);
1463
+ j += n << 20;
1464
+ if (j >> 20 <= 0) z = scalbn(z, n);
1465
+ else z = reinterpret<f64>((reinterpret<u64>(z) & 0xffffffff) | ((<u64>j) << 32));
1466
+ return s * z;
1467
+ }
1468
+ }
1469
+
1470
+ export function seedRandom(value: i64): void {
1471
+ // Instead zero seed use golden ratio:
1472
+ // phi = (1 + sqrt(5)) / 2
1473
+ // trunc(2^64 / phi) = 0x9e3779b97f4a7c15
1474
+ if (value == 0) value = 0x9e3779b97f4a7c15;
1475
+ random_state0_64 = murmurHash3(value);
1476
+ random_state1_64 = murmurHash3(~random_state0_64);
1477
+ random_state0_32 = splitMix32(<u32>value);
1478
+ random_state1_32 = splitMix32(random_state0_32);
1479
+ random_seeded = true;
1480
+ }
1481
+
1482
+ export function random(): f64 {
1483
+ // see: v8/src/base/utils/random-number-generator.cc
1484
+ if (!random_seeded) seedRandom(reinterpret<i64>(seed()));
1485
+ let s1 = random_state0_64;
1486
+ let s0 = random_state1_64;
1487
+ random_state0_64 = s0;
1488
+ s1 ^= s1 << 23;
1489
+ s1 ^= s1 >> 17;
1490
+ s1 ^= s0;
1491
+ s1 ^= s0 >> 26;
1492
+ random_state1_64 = s1;
1493
+ let r = (s0 >> 12) | 0x3ff0000000000000;
1494
+ return reinterpret<f64>(r) - 1;
1495
+ }
1496
+
1497
+ export function round(x: f64): f64 {
1498
+ if (ASC_SHRINK_LEVEL > 0) {
1499
+ return builtin_ceil<f64>(x) - f64(builtin_ceil<f64>(x) - 0.5 > x);
1500
+ } else {
1501
+ let roundUp = builtin_ceil<f64>(x);
1502
+ return select<f64>(roundUp, roundUp - 1.0, roundUp - 0.5 <= x);
1503
+ }
1504
+ }
1505
+
1506
+ export function sign(x: f64): f64 {
1507
+ if (ASC_SHRINK_LEVEL > 0) {
1508
+ return select<f64>(builtin_copysign<f64>(1, x), x, builtin_abs(x) > 0);
1509
+ } else {
1510
+ return select<f64>(1, select<f64>(-1, x, x < 0), x > 0);
1511
+ }
1512
+ }
1513
+
1514
+ // @ts-ignore: decorator
1515
+ @inline
1516
+ export function signbit(x: f64): bool {
1517
+ return bool(reinterpret<u64>(x) >>> 63);
1518
+ }
1519
+
1520
+ export function sin(x: f64): f64 {
1521
+ // see: musl/src/math/sin.c
1522
+ let u = reinterpret<u64>(x);
1523
+ let ux = u32(u >> 32);
1524
+ let sign = ux >> 31;
1525
+
1526
+ ux &= 0x7fffffff;
1527
+
1528
+ // |x| ~< pi/4
1529
+ if (ux <= 0x3fe921fb) {
1530
+ if (ux < 0x3e500000) {
1531
+ // |x| < 2**-26
1532
+ return x;
1533
+ }
1534
+ return sin_kern(x, 0.0, 0);
1535
+ }
1536
+
1537
+ // sin(Inf or NaN) is NaN
1538
+ if (ux >= 0x7ff00000) return x - x;
1539
+
1540
+ // argument reduction needed
1541
+ let n = rempio2(x, u, sign);
1542
+ let y0 = rempio2_y0;
1543
+ let y1 = rempio2_y1;
1544
+
1545
+ x = n & 1 ? cos_kern(y0, y1) : sin_kern(y0, y1, 1);
1546
+ return n & 2 ? -x : x;
1547
+ }
1548
+
1549
+ export function sinh(x: f64): f64 {
1550
+ // see: musl/src/math/sinh.c
1551
+ let u = reinterpret<u64>(x) & 0x7fffffffffffffff;
1552
+ let a = reinterpret<f64>(u);
1553
+ let w = u32(u >> 32);
1554
+ let h = builtin_copysign(0.5, x);
1555
+ if (w < 0x40862e42) {
1556
+ let t = expm1(a);
1557
+ if (w < 0x3ff00000) {
1558
+ if (w < 0x3ff00000 - (26 << 20)) return x;
1559
+ return h * (2 * t - (t * t) / (t + 1));
1560
+ }
1561
+ return h * (t + t / (t + 1));
1562
+ }
1563
+ return expo2(a, 2 * h);
1564
+ }
1565
+
1566
+ // @ts-ignore: decorator
1567
+ @inline
1568
+ export function sqrt(x: f64): f64 {
1569
+ return builtin_sqrt<f64>(x);
1570
+ }
1571
+
1572
+ export function tan(x: f64): f64 {
1573
+ // see: musl/src/math/tan.c
1574
+ let u = reinterpret<u64>(x);
1575
+ let ux = u32(u >> 32);
1576
+ let sign = ux >>> 31;
1577
+
1578
+ ux &= 0x7fffffff;
1579
+
1580
+ // |x| ~< pi/4
1581
+ if (ux <= 0x3fe921fb) {
1582
+ if (ux < 0x3e400000) {
1583
+ // |x| < 2**-27
1584
+ return x;
1585
+ }
1586
+ return tan_kern(x, 0.0, 1);
1587
+ }
1588
+
1589
+ // tan(Inf or NaN) is NaN
1590
+ if (ux >= 0x7ff00000) return x - x;
1591
+
1592
+ let n = rempio2(x, u, sign);
1593
+ return tan_kern(rempio2_y0, rempio2_y1, 1 - ((n & 1) << 1));
1594
+ }
1595
+
1596
+ export function tanh(x: f64): f64 {
1597
+ // see: musl/src/math/tanh.c
1598
+ let u = reinterpret<u64>(x);
1599
+ u &= 0x7fffffffffffffff;
1600
+ let y = reinterpret<f64>(u);
1601
+ let w = u32(u >> 32);
1602
+ let t: f64;
1603
+ if (w > 0x3fe193ea) {
1604
+ if (w > 0x40340000) {
1605
+ t = 1 - 0 / y;
1606
+ } else {
1607
+ t = expm1(2 * y);
1608
+ t = 1 - 2 / (t + 2);
1609
+ }
1610
+ } else if (w > 0x3fd058ae) {
1611
+ t = expm1(2 * y);
1612
+ t = t / (t + 2);
1613
+ } else if (w >= 0x00100000) {
1614
+ t = expm1(-2 * y);
1615
+ t = -t / (t + 2);
1616
+ } else t = y;
1617
+ return builtin_copysign<f64>(t, x);
1618
+ }
1619
+
1620
+ // @ts-ignore: decorator
1621
+ @inline
1622
+ export function trunc(x: f64): f64 {
1623
+ return builtin_trunc<f64>(x);
1624
+ }
1625
+
1626
+ export function scalbn(x: f64, n: i32): f64 {
1627
+ // see: https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c
1628
+ const Ox1p53 = reinterpret<f64>(0x4340000000000000),
1629
+ Ox1p1023 = reinterpret<f64>(0x7fe0000000000000),
1630
+ Ox1p_1022 = reinterpret<f64>(0x0010000000000000);
1631
+
1632
+ let y = x;
1633
+ if (n > 1023) {
1634
+ y *= Ox1p1023;
1635
+ n -= 1023;
1636
+ if (n > 1023) {
1637
+ y *= Ox1p1023;
1638
+ n = builtin_min<i32>(n - 1023, 1023);
1639
+ }
1640
+ } else if (n < -1022) {
1641
+ // make sure final n < -53 to avoid double
1642
+ // rounding in the subnormal range
1643
+ y *= Ox1p_1022 * Ox1p53;
1644
+ n += 1022 - 53;
1645
+ if (n < -1022) {
1646
+ y *= Ox1p_1022 * Ox1p53;
1647
+ n = builtin_max<i32>(n + 1022 - 53, -1022);
1648
+ }
1649
+ }
1650
+ return y * reinterpret<f64>((<u64>(0x3ff + n)) << 52);
1651
+ }
1652
+
1653
+ export function mod(x: f64, y: f64): f64 {
1654
+ // see: musl/src/math/fmod.c
1655
+ if (builtin_abs<f64>(y) == 1.0) {
1656
+ // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))
1657
+ // TODO: move this rule to compiler's optimization pass.
1658
+ // It could be apply for any x % C_pot, where "C_pot" is pow of two const.
1659
+ return builtin_copysign<f64>(x - builtin_trunc<f64>(x), x);
1660
+ }
1661
+ let ux = reinterpret<u64>(x);
1662
+ let uy = reinterpret<u64>(y);
1663
+ let ex = i64((ux >> 52) & 0x7ff);
1664
+ let ey = i64((uy >> 52) & 0x7ff);
1665
+ let sx = ux >> 63;
1666
+ let uy1 = uy << 1;
1667
+ if (uy1 == 0 || ex == 0x7ff || isNaN<f64>(y)) {
1668
+ let m = x * y;
1669
+ return m / m;
1670
+ }
1671
+ let ux1 = ux << 1;
1672
+ if (ux1 <= uy1) {
1673
+ return x * f64(ux1 != uy1);
1674
+ }
1675
+ if (!ex) {
1676
+ ex -= builtin_clz<i64>(ux << 12);
1677
+ ux <<= 1 - ex;
1678
+ } else {
1679
+ ux &= u64(-1) >> 12;
1680
+ ux |= 1 << 52;
1681
+ }
1682
+ if (!ey) {
1683
+ ey -= builtin_clz<i64>(uy << 12);
1684
+ uy <<= 1 - ey;
1685
+ } else {
1686
+ uy &= u64(-1) >> 12;
1687
+ uy |= 1 << 52;
1688
+ }
1689
+ while (ex > ey) {
1690
+ if (ux >= uy) {
1691
+ if (ux == uy) return 0 * x;
1692
+ ux -= uy;
1693
+ }
1694
+ ux <<= 1;
1695
+ --ex;
1696
+ }
1697
+ if (ux >= uy) {
1698
+ if (ux == uy) return 0 * x;
1699
+ ux -= uy;
1700
+ }
1701
+ // for (; !(ux >> 52); ux <<= 1) --ex;
1702
+ let shift = builtin_clz<i64>(ux << 11);
1703
+ ex -= shift;
1704
+ ux <<= shift;
1705
+ if (ex > 0) {
1706
+ ux -= 1 << 52;
1707
+ ux |= ex << 52;
1708
+ } else {
1709
+ ux >>= -ex + 1;
1710
+ }
1711
+ return reinterpret<f64>(ux | (sx << 63));
1712
+ }
1713
+
1714
+ export function rem(x: f64, y: f64): f64 {
1715
+ // see: musl/src/math/remquo.c
1716
+ let ux = reinterpret<u64>(x);
1717
+ let uy = reinterpret<u64>(y);
1718
+ let ex = i64((ux >> 52) & 0x7ff);
1719
+ let ey = i64((uy >> 52) & 0x7ff);
1720
+ if (uy << 1 == 0 || ex == 0x7ff || isNaN(y)) {
1721
+ let m = x * y;
1722
+ return m / m;
1723
+ }
1724
+ if (ux << 1 == 0) return x;
1725
+ let uxi = ux;
1726
+ if (!ex) {
1727
+ ex -= builtin_clz<i64>(uxi << 12);
1728
+ uxi <<= 1 - ex;
1729
+ } else {
1730
+ uxi &= u64(-1) >> 12;
1731
+ uxi |= 1 << 52;
1732
+ }
1733
+ if (!ey) {
1734
+ ey -= builtin_clz<i64>(uy << 12);
1735
+ uy <<= 1 - ey;
1736
+ } else {
1737
+ uy &= u64(-1) >> 12;
1738
+ uy |= 1 << 52;
1739
+ }
1740
+ let q: u32 = 0;
1741
+ do {
1742
+ if (ex < ey) {
1743
+ if (ex + 1 == ey) break; // goto end
1744
+ return x;
1745
+ }
1746
+ while (ex > ey) {
1747
+ if (uxi >= uy) {
1748
+ uxi -= uy;
1749
+ ++q;
1750
+ }
1751
+ uxi <<= 1;
1752
+ q <<= 1;
1753
+ --ex;
1754
+ }
1755
+ if (uxi >= uy) {
1756
+ uxi -= uy;
1757
+ ++q;
1758
+ }
1759
+ if (uxi == 0) ex = -60;
1760
+ else {
1761
+ let shift = builtin_clz<i64>(uxi << 11);
1762
+ ex -= shift;
1763
+ uxi <<= shift;
1764
+ }
1765
+ break;
1766
+ } while (false);
1767
+ // end:
1768
+ if (ex > 0) {
1769
+ uxi -= 1 << 52;
1770
+ uxi |= ex << 52;
1771
+ } else {
1772
+ uxi >>= -ex + 1;
1773
+ }
1774
+ x = reinterpret<f64>(uxi);
1775
+ y = builtin_abs<f64>(y);
1776
+ let x2 = x + x;
1777
+ if (ex == ey || (ex + 1 == ey && (x2 > y || (x2 == y && <bool>(q & 1))))) {
1778
+ x -= y;
1779
+ // ++q;
1780
+ }
1781
+ return <i64>ux < 0 ? -x : x;
1782
+ }
1783
+
1784
+ export function sincos(x: f64): void {
1785
+ // see: musl/tree/src/math/sincos.c
1786
+ let u = reinterpret<u64>(x);
1787
+ let ux = u32(u >> 32);
1788
+ let sign = ux >> 31;
1789
+ ux &= 0x7fffffff;
1790
+
1791
+ if (ux <= 0x3fe921fb) {
1792
+ // |x| ~<= π/4
1793
+ if (ux < 0x3e46a09e) {
1794
+ // if |x| < 2**-27 * sqrt(2)
1795
+ sincos_sin = x;
1796
+ sincos_cos = 1;
1797
+ return;
1798
+ }
1799
+ sincos_sin = sin_kern(x, 0, 0);
1800
+ sincos_cos = cos_kern(x, 0);
1801
+ return;
1802
+ }
1803
+ // sin(Inf or NaN) is NaN
1804
+ if (ux >= 0x7f800000) {
1805
+ let xx = x - x;
1806
+ sincos_sin = xx;
1807
+ sincos_cos = xx;
1808
+ return;
1809
+ }
1810
+ // general argument reduction needed
1811
+ let n = rempio2(x, u, sign);
1812
+ let y0 = rempio2_y0;
1813
+ let y1 = rempio2_y1;
1814
+ let s = sin_kern(y0, y1, 1);
1815
+ let c = cos_kern(y0, y1);
1816
+ let sin = s,
1817
+ cos = c;
1818
+ if (n & 1) {
1819
+ sin = c;
1820
+ cos = -s;
1821
+ }
1822
+ if (n & 2) {
1823
+ sin = -sin;
1824
+ cos = -cos;
1825
+ }
1826
+ sincos_sin = sin;
1827
+ sincos_cos = cos;
1828
+ }
1829
+ }
1830
+
1831
+ // @ts-ignore: decorator
1832
+ @lazy let rempio2f_y: f64;
1833
+
1834
+ // @ts-ignore: decorator
1835
+ @lazy @inline const PIO2F_TABLE = memory.data<u64>([
1836
+ 0xa2f9836e4e441529, 0xfc2757d1f534ddc0, 0xdb6295993c439041, 0xfe5163abdebbc561,
1837
+ ]);
1838
+
1839
+ function Rf(z: f32): f32 {
1840
+ // Rational approximation of (asin(x)-x)/x^3
1841
+ const // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above
1842
+ pS0 = reinterpret<f32>(0x3e2aaa75), // 1.6666586697e-01f
1843
+ pS1 = reinterpret<f32>(0xbd2f13ba), // -4.2743422091e-02f
1844
+ pS2 = reinterpret<f32>(0xbc0dd36b), // -8.6563630030e-03f
1845
+ qS1 = reinterpret<f32>(0xbf34e5ae); // -7.0662963390e-01f
1846
+
1847
+ let p = z * (pS0 + z * (pS1 + z * pS2));
1848
+ let q: f32 = 1 + z * qS1;
1849
+ return p / q;
1850
+ }
1851
+
1852
+ // @ts-ignore: decorator
1853
+ @inline
1854
+ function expo2f(x: f32, sign: f32): f32 {
1855
+ // exp(x)/2 for x >= log(DBL_MAX)
1856
+ const // see: musl/src/math/__expo2f.c
1857
+ k = <u32>235,
1858
+ kln2 = reinterpret<f32>(0x4322e3bc); // 0x1.45c778p+7f
1859
+ let scale = reinterpret<f32>(u32(0x7f + (k >> 1)) << 23);
1860
+ // in directed rounding correct sign before rounding or overflow is important
1861
+ return NativeMathf.exp(x - kln2) * (sign * scale) * scale;
1862
+ }
1863
+
1864
+ // @ts-ignore: decorator
1865
+ @inline
1866
+ function pio2f_large_quot(x: f32, u: i32): i32 {
1867
+ // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
1868
+ const coeff = reinterpret<f64>(0x3bf921fb54442d18); // π * 0x1p-65 = 8.51530395021638647334e-20
1869
+
1870
+ let offset = (u >> 23) - 152;
1871
+ let shift = u64(offset & 63);
1872
+ let tblPtr = PIO2F_TABLE + ((offset >> 6) << 3);
1873
+
1874
+ let b0 = load<u64>(tblPtr, 0 << 3);
1875
+ let b1 = load<u64>(tblPtr, 1 << 3);
1876
+ let lo: u64;
1877
+
1878
+ if (shift > 32) {
1879
+ let b2 = load<u64>(tblPtr, 2 << 3);
1880
+ lo = b2 >> (96 - shift);
1881
+ lo |= b1 << (shift - 32);
1882
+ } else {
1883
+ lo = b1 >> (32 - shift);
1884
+ }
1885
+
1886
+ let hi = (b1 >> (64 - shift)) | (b0 << shift);
1887
+ let mantissa: u64 = (u & 0x007fffff) | 0x00800000;
1888
+ let product = mantissa * hi + ((mantissa * lo) >> 32);
1889
+ let r: i64 = product << 2;
1890
+ let q = i32((product >> 62) + (r >>> 63));
1891
+ rempio2f_y = copysign<f64>(coeff, x) * <f64>r;
1892
+ return q;
1893
+ }
1894
+
1895
+ // @ts-ignore: decorator
1896
+ @inline
1897
+ function rempio2f(x: f32, u: u32, sign: i32): i32 {
1898
+ // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
1899
+ const pi2hi = reinterpret<f64>(0x3ff921fb50000000), // 1.57079631090164184570
1900
+ pi2lo = reinterpret<f64>(0x3e5110b4611a6263), // 1.58932547735281966916e-8
1901
+ _2_pi = reinterpret<f64>(0x3fe45f306dc9c883); // 0.63661977236758134308
1902
+
1903
+ if (u < 0x4dc90fdb) {
1904
+ // π * 0x1p28
1905
+ let q = nearest(x * _2_pi);
1906
+ rempio2f_y = x - q * pi2hi - q * pi2lo;
1907
+ return <i32>q;
1908
+ }
1909
+
1910
+ let q = pio2f_large_quot(x, u);
1911
+ return select(-q, q, sign);
1912
+ }
1913
+
1914
+ // |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]).
1915
+ // @ts-ignore: decorator
1916
+ @inline
1917
+ function sin_kernf(x: f64): f32 {
1918
+ // see: musl/tree/src/math/__sindf.c
1919
+ const S1 = reinterpret<f64>(0xbfc5555554cbac77), // -0x15555554cbac77.0p-55
1920
+ S2 = reinterpret<f64>(0x3f811110896efbb2), // 0x111110896efbb2.0p-59
1921
+ S3 = reinterpret<f64>(0xbf2a00f9e2cae774), // -0x1a00f9e2cae774.0p-65
1922
+ S4 = reinterpret<f64>(0x3ec6cd878c3b46a7); // 0x16cd878c3b46a7.0p-71
1923
+
1924
+ let z = x * x;
1925
+ let w = z * z;
1926
+ let r = S3 + z * S4;
1927
+ let s = z * x;
1928
+ return f32(x + s * (S1 + z * S2) + s * w * r);
1929
+ }
1930
+
1931
+ // |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]).
1932
+ // @ts-ignore: decorator
1933
+ @inline
1934
+ function cos_kernf(x: f64): f32 {
1935
+ // see: musl/tree/src/math/__cosdf.c
1936
+ const C0 = reinterpret<f64>(0xbfdffffffd0c5e81), // -0x1ffffffd0c5e81.0p-54
1937
+ C1 = reinterpret<f64>(0x3fa55553e1053a42), // 0x155553e1053a42.0p-57
1938
+ C2 = reinterpret<f64>(0xbf56c087e80f1e27), // -0x16c087e80f1e27.0p-62
1939
+ C3 = reinterpret<f64>(0x3ef99342e0ee5069); // 0x199342e0ee5069.0p-68
1940
+
1941
+ let z = x * x;
1942
+ let w = z * z;
1943
+ let r = C2 + z * C3;
1944
+ return f32(1 + z * C0 + w * C1 + w * z * r);
1945
+ }
1946
+
1947
+ // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]).
1948
+ // @ts-ignore: decorator
1949
+ @inline
1950
+ function tan_kernf(x: f64, odd: i32): f32 {
1951
+ // see: musl/tree/src/math/__tandf.c
1952
+ const T0 = reinterpret<f64>(0x3fd5554d3418c99f), // 0x15554d3418c99f.0p-54
1953
+ T1 = reinterpret<f64>(0x3fc112fd38999f72), // 0x1112fd38999f72.0p-55
1954
+ T2 = reinterpret<f64>(0x3fab54c91d865afe), // 0x1b54c91d865afe.0p-57
1955
+ T3 = reinterpret<f64>(0x3f991df3908c33ce), // 0x191df3908c33ce.0p-58
1956
+ T4 = reinterpret<f64>(0x3f685dadfcecf44e), // 0x185dadfcecf44e.0p-61
1957
+ T5 = reinterpret<f64>(0x3f8362b9bf971bcd); // 0x1362b9bf971bcd.0p-59
1958
+
1959
+ let z = x * x;
1960
+ let r = T4 + z * T5;
1961
+ let t = T2 + z * T3;
1962
+ let w = z * z;
1963
+ let s = z * x;
1964
+ let u = T0 + z * T1;
1965
+
1966
+ r = x + s * u + s * w * (t + w * r);
1967
+ return f32(odd ? -1 / r : r);
1968
+ }
1969
+
1970
+ // See: jdh8/metallic/src/math/float/log2f.c and jdh8/metallic/src/math/float/kernel/atanh.h
1971
+ // @ts-ignore: decorator
1972
+ @inline
1973
+ function log2f(x: f64): f64 {
1974
+ const log2e = reinterpret<f64>(0x3ff71547652b82fe), // 1.44269504088896340736
1975
+ c0 = reinterpret<f64>(0x3fd555554fd9caef), // 0.33333332822728226129
1976
+ c1 = reinterpret<f64>(0x3fc999a7a8af4132), // 0.20000167595436263505
1977
+ c2 = reinterpret<f64>(0x3fc2438d79437030), // 0.14268654271188685375
1978
+ c3 = reinterpret<f64>(0x3fbe2f663b001c97); // 0.11791075649681414150
1979
+
1980
+ let i = reinterpret<i64>(x);
1981
+ let exponent = (i - 0x3fe6a09e667f3bcd) >> 52;
1982
+ x = reinterpret<f64>(i - (exponent << 52));
1983
+ x = (x - 1) / (x + 1);
1984
+ let xx = x * x;
1985
+ let y = x + x * xx * (c0 + c1 * xx + (c2 + c3 * xx) * (xx * xx));
1986
+ return 2 * log2e * y + <f64>exponent;
1987
+ }
1988
+
1989
+ // See: jdh8/metallic/src/math/float/exp2f.h and jdh8/metallic/blob/master/src/math/float/kernel/exp2f.h
1990
+ // @ts-ignore: decorator
1991
+ @inline
1992
+ function exp2f(x: f64): f64 {
1993
+ const c0 = reinterpret<f64>(0x3fe62e4302fcc24a), // 6.931471880289532425e-1
1994
+ c1 = reinterpret<f64>(0x3fcebfbe07d97b91), // 2.402265108421173406e-1
1995
+ c2 = reinterpret<f64>(0x3fac6af6ccfc1a65), // 5.550357105498874537e-2
1996
+ c3 = reinterpret<f64>(0x3f83b29e3ce9aef6), // 9.618030771171497658e-3
1997
+ c4 = reinterpret<f64>(0x3f55f0896145a89f), // 1.339086685300950937e-3
1998
+ c5 = reinterpret<f64>(0x3f2446c81e384864); // 1.546973499989028719e-4
1999
+
2000
+ if (x < -1022) return 0;
2001
+ if (x >= 1024) return Infinity;
2002
+
2003
+ let n = nearest(x);
2004
+ x -= n;
2005
+ let xx = x * x;
2006
+ let y = 1 + x * (c0 + c1 * x + (c2 + c3 * x) * xx + (c4 + c5 * x) * (xx * xx));
2007
+ return reinterpret<f64>(reinterpret<i64>(y) + ((<i64>n) << 52));
2008
+ }
2009
+
2010
+ export namespace NativeMathf {
2011
+ // @ts-ignore: decorator
2012
+ @lazy
2013
+ export const E = <f32>NativeMath.E;
2014
+
2015
+ // @ts-ignore: decorator
2016
+ @lazy
2017
+ export const LN2 = <f32>NativeMath.LN2;
2018
+
2019
+ // @ts-ignore: decorator
2020
+ @lazy
2021
+ export const LN10 = <f32>NativeMath.LN10;
2022
+
2023
+ // @ts-ignore: decorator
2024
+ @lazy
2025
+ export const LOG2E = <f32>NativeMath.LOG2E;
2026
+
2027
+ // @ts-ignore: decorator
2028
+ @lazy
2029
+ export const LOG10E = <f32>NativeMath.LOG10E;
2030
+
2031
+ // @ts-ignore: decorator
2032
+ @lazy
2033
+ export const PI = <f32>NativeMath.PI;
2034
+
2035
+ // @ts-ignore: decorator
2036
+ @lazy
2037
+ export const SQRT1_2 = <f32>NativeMath.SQRT1_2;
2038
+
2039
+ // @ts-ignore: decorator
2040
+ @lazy
2041
+ export const SQRT2 = <f32>NativeMath.SQRT2;
2042
+
2043
+ // @ts-ignore: decorator
2044
+ @lazy
2045
+ export let sincos_sin: f32 = 0;
2046
+
2047
+ // @ts-ignore: decorator
2048
+ @lazy
2049
+ export let sincos_cos: f32 = 0;
2050
+
2051
+ // @ts-ignore: decorator
2052
+ @inline
2053
+ export function abs(x: f32): f32 {
2054
+ return builtin_abs<f32>(x);
2055
+ }
2056
+
2057
+ export function acos(x: f32): f32 {
2058
+ // see: musl/src/math/acosf.c and SUN COPYRIGHT NOTICE above
2059
+ const pio2_hi = reinterpret<f32>(0x3fc90fda), // 1.5707962513e+00f
2060
+ pio2_lo = reinterpret<f32>(0x33a22168), // 7.5497894159e-08f
2061
+ Ox1p_120f = reinterpret<f32>(0x03800000); // 0x1p-120f
2062
+
2063
+ let hx = reinterpret<u32>(x);
2064
+ let ix = hx & 0x7fffffff;
2065
+ if (ix >= 0x3f800000) {
2066
+ if (ix == 0x3f800000) {
2067
+ return select<f32>(2 * pio2_hi + Ox1p_120f, 0, <i32>hx < 0);
2068
+ }
2069
+ return 0 / (x - x);
2070
+ }
2071
+ if (ix < 0x3f000000) {
2072
+ if (ix <= 0x32800000) return pio2_hi + Ox1p_120f;
2073
+ return pio2_hi - (x - (pio2_lo - x * Rf(x * x)));
2074
+ }
2075
+ let z: f32, w: f32, s: f32;
2076
+ if (<i32>hx < 0) {
2077
+ // z = (1 + x) * 0.5;
2078
+ z = 0.5 + x * 0.5;
2079
+ s = builtin_sqrt<f32>(z);
2080
+ w = Rf(z) * s - pio2_lo;
2081
+ return 2 * (pio2_hi - (s + w));
2082
+ }
2083
+ // z = (1 - x) * 0.5;
2084
+ z = 0.5 - x * 0.5;
2085
+ s = builtin_sqrt<f32>(z);
2086
+ hx = reinterpret<u32>(s);
2087
+ let df = reinterpret<f32>(hx & 0xfffff000);
2088
+ let c = (z - df * df) / (s + df);
2089
+ w = Rf(z) * s + c;
2090
+ return 2 * (df + w);
2091
+ }
2092
+
2093
+ export function acosh(x: f32): f32 {
2094
+ // see: musl/src/math/acoshf.c
2095
+ const s = reinterpret<f32>(0x3f317218); // 0.693147180559945309417232121458176568f
2096
+ let u = reinterpret<u32>(x);
2097
+ let a = u & 0x7fffffff;
2098
+ if (a < 0x3f800000 + (1 << 23)) {
2099
+ // |x| < 2, invalid if x < 1
2100
+ let xm1 = x - 1;
2101
+ return log1p(xm1 + builtin_sqrt(xm1 * (xm1 + 2)));
2102
+ }
2103
+ if (u < 0x3f800000 + (12 << 23)) {
2104
+ // 2 <= x < 0x1p12
2105
+ return log(2 * x - 1 / (x + builtin_sqrt<f32>(x * x - 1)));
2106
+ }
2107
+ // x >= 0x1p12 or x <= -2 or NaN
2108
+ return log(x) + s;
2109
+ }
2110
+
2111
+ export function asin(x: f32): f32 {
2112
+ // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above
2113
+ const pio2 = reinterpret<f32>(0x3fc90fdb), // 1.570796326794896558e+00f
2114
+ Ox1p_120f = reinterpret<f32>(0x03800000); // 0x1p-120f
2115
+
2116
+ let sx = x;
2117
+ let hx = reinterpret<u32>(x) & 0x7fffffff;
2118
+ if (hx >= 0x3f800000) {
2119
+ if (hx == 0x3f800000) return x * pio2 + Ox1p_120f;
2120
+ return 0 / (x - x);
2121
+ }
2122
+ if (hx < 0x3f000000) {
2123
+ if (hx < 0x39800000 && hx >= 0x00800000) return x;
2124
+ return x + x * Rf(x * x);
2125
+ }
2126
+ // let z: f32 = (1 - builtin_abs<f32>(x)) * 0.5;
2127
+ let z: f32 = 0.5 - builtin_abs<f32>(x) * 0.5;
2128
+ let s = builtin_sqrt<f64>(z); // sic
2129
+ x = f32(pio2 - 2 * (s + s * Rf(z)));
2130
+ return builtin_copysign(x, sx);
2131
+ }
2132
+
2133
+ export function asinh(x: f32): f32 {
2134
+ // see: musl/src/math/asinhf.c
2135
+ const c = reinterpret<f32>(0x3f317218); // 0.693147180559945309417232121458176568f
2136
+ let u = reinterpret<u32>(x) & 0x7fffffff;
2137
+ let y = reinterpret<f32>(u);
2138
+ if (u >= 0x3f800000 + (12 << 23)) y = log(y) + c;
2139
+ else if (u >= 0x3f800000 + (1 << 23)) y = log(2 * y + 1 / (builtin_sqrt<f32>(y * y + 1) + y));
2140
+ else if (u >= 0x3f800000 - (12 << 23)) y = log1p(y + (y * y) / (builtin_sqrt<f32>(y * y + 1) + 1));
2141
+ return builtin_copysign(y, x);
2142
+ }
2143
+
2144
+ export function atan(x: f32): f32 {
2145
+ // see: musl/src/math/atanf.c and SUN COPYRIGHT NOTICE above
2146
+ const atanhi0 = reinterpret<f32>(0x3eed6338), // 4.6364760399e-01f
2147
+ atanhi1 = reinterpret<f32>(0x3f490fda), // 7.8539812565e-01f
2148
+ atanhi2 = reinterpret<f32>(0x3f7b985e), // 9.8279368877e-01f
2149
+ atanhi3 = reinterpret<f32>(0x3fc90fda), // 1.5707962513e+00f
2150
+ atanlo0 = reinterpret<f32>(0x31ac3769), // 5.0121582440e-09f
2151
+ atanlo1 = reinterpret<f32>(0x33222168), // 3.7748947079e-08f
2152
+ atanlo2 = reinterpret<f32>(0x33140fb4), // 3.4473217170e-08f
2153
+ atanlo3 = reinterpret<f32>(0x33a22168), // 7.5497894159e-08f
2154
+ aT0 = reinterpret<f32>(0x3eaaaaa9), // 3.3333328366e-01f
2155
+ aT1 = reinterpret<f32>(0xbe4cca98), // -1.9999158382e-01f
2156
+ aT2 = reinterpret<f32>(0x3e11f50d), // 1.4253635705e-01f
2157
+ aT3 = reinterpret<f32>(0xbdda1247), // -1.0648017377e-01f
2158
+ aT4 = reinterpret<f32>(0x3d7cac25), // 6.1687607318e-02f
2159
+ Ox1p_120f = reinterpret<f32>(0x03800000); // 0x1p-120f
2160
+
2161
+ let ix = reinterpret<u32>(x);
2162
+ let sx = x;
2163
+ ix &= 0x7fffffff;
2164
+ let z: f32;
2165
+ if (ix >= 0x4c800000) {
2166
+ if (isNaN(x)) return x;
2167
+ z = atanhi3 + Ox1p_120f;
2168
+ return builtin_copysign(z, sx);
2169
+ }
2170
+ let id: i32;
2171
+ if (ix < 0x3ee00000) {
2172
+ if (ix < 0x39800000) return x;
2173
+ id = -1;
2174
+ } else {
2175
+ x = builtin_abs<f32>(x);
2176
+ if (ix < 0x3f980000) {
2177
+ if (ix < 0x3f300000) {
2178
+ id = 0;
2179
+ x = (2.0 * x - 1.0) / (2.0 + x);
2180
+ } else {
2181
+ id = 1;
2182
+ x = (x - 1.0) / (x + 1.0);
2183
+ }
2184
+ } else {
2185
+ if (ix < 0x401c0000) {
2186
+ id = 2;
2187
+ x = (x - 1.5) / (1.0 + 1.5 * x);
2188
+ } else {
2189
+ id = 3;
2190
+ x = -1.0 / x;
2191
+ }
2192
+ }
2193
+ }
2194
+ z = x * x;
2195
+ let w = z * z;
2196
+ let s1 = z * (aT0 + w * (aT2 + w * aT4));
2197
+ let s2 = w * (aT1 + w * aT3);
2198
+ let s3 = x * (s1 + s2);
2199
+ if (id < 0) return x - s3;
2200
+ switch (id) {
2201
+ case 0: {
2202
+ z = atanhi0 - (s3 - atanlo0 - x);
2203
+ break;
2204
+ }
2205
+ case 1: {
2206
+ z = atanhi1 - (s3 - atanlo1 - x);
2207
+ break;
2208
+ }
2209
+ case 2: {
2210
+ z = atanhi2 - (s3 - atanlo2 - x);
2211
+ break;
2212
+ }
2213
+ case 3: {
2214
+ z = atanhi3 - (s3 - atanlo3 - x);
2215
+ break;
2216
+ }
2217
+ default:
2218
+ unreachable();
2219
+ }
2220
+ return builtin_copysign(z, sx);
2221
+ }
2222
+
2223
+ export function atanh(x: f32): f32 {
2224
+ // see: musl/src/math/atanhf.c
2225
+ let u = reinterpret<u32>(x);
2226
+ let y = builtin_abs(x);
2227
+ if (u < 0x3f800000 - (1 << 23)) {
2228
+ if (u >= 0x3f800000 - (32 << 23)) y = 0.5 * log1p(2 * y * (1.0 + y / (1 - y)));
2229
+ } else y = 0.5 * log1p(2 * (y / (1 - y)));
2230
+ return builtin_copysign(y, x);
2231
+ }
2232
+
2233
+ export function atan2(y: f32, x: f32): f32 {
2234
+ // see: musl/src/math/atan2f.c and SUN COPYRIGHT NOTICE above
2235
+ const pi = reinterpret<f32>(0x40490fdb), // 3.1415927410e+00f
2236
+ pi_lo = reinterpret<f32>(0xb3bbbd2e); // -8.7422776573e-08f
2237
+
2238
+ if (isNaN(x) || isNaN(y)) return x + y;
2239
+ let ix = reinterpret<u32>(x);
2240
+ let iy = reinterpret<u32>(y);
2241
+ if (ix == 0x3f800000) return atan(y);
2242
+ let m = u32(((iy >> 31) & 1) | ((ix >> 30) & 2));
2243
+ ix &= 0x7fffffff;
2244
+ iy &= 0x7fffffff;
2245
+ if (iy == 0) {
2246
+ switch (m) {
2247
+ case 0:
2248
+ case 1:
2249
+ return y;
2250
+ case 2:
2251
+ return pi;
2252
+ case 3:
2253
+ return -pi;
2254
+ }
2255
+ }
2256
+ if (ix == 0) return m & 1 ? -pi / 2 : pi / 2;
2257
+ if (ix == 0x7f800000) {
2258
+ if (iy == 0x7f800000) {
2259
+ let t: f32 = m & 2 ? (3 * pi) / 4 : pi / 4;
2260
+ return m & 1 ? -t : t;
2261
+ } else {
2262
+ let t: f32 = m & 2 ? pi : 0.0;
2263
+ return m & 1 ? -t : t;
2264
+ }
2265
+ }
2266
+ if (ix + (26 << 23) < iy || iy == 0x7f800000) return m & 1 ? -pi / 2 : pi / 2;
2267
+ let z: f32;
2268
+ if (m & 2 && iy + (26 << 23) < ix) z = 0.0;
2269
+ else z = atan(builtin_abs<f32>(y / x));
2270
+ switch (m) {
2271
+ case 0:
2272
+ return z;
2273
+ case 1:
2274
+ return -z;
2275
+ case 2:
2276
+ return pi - (z - pi_lo);
2277
+ case 3:
2278
+ return z - pi_lo - pi;
2279
+ }
2280
+ unreachable();
2281
+ return 0;
2282
+ }
2283
+
2284
+ export function cbrt(x: f32): f32 {
2285
+ // see: musl/src/math/cbrtf.c and SUN COPYRIGHT NOTICE above
2286
+ const B1 = <u32>709958130,
2287
+ B2 = <u32>642849266,
2288
+ Ox1p24f = reinterpret<f32>(0x4b800000);
2289
+
2290
+ let u = reinterpret<u32>(x);
2291
+ let hx = u & 0x7fffffff;
2292
+ if (hx >= 0x7f800000) return x + x;
2293
+ if (hx < 0x00800000) {
2294
+ if (hx == 0) return x;
2295
+ u = reinterpret<u32>(x * Ox1p24f);
2296
+ hx = u & 0x7fffffff;
2297
+ hx = hx / 3 + B2;
2298
+ } else {
2299
+ hx = hx / 3 + B1;
2300
+ }
2301
+ u &= 0x80000000;
2302
+ u |= hx;
2303
+ let t = <f64>reinterpret<f32>(u);
2304
+ let r = t * t * t;
2305
+ t = (t * (<f64>x + x + r)) / (x + r + r);
2306
+ r = t * t * t;
2307
+ t = (t * (<f64>x + x + r)) / (x + r + r);
2308
+ return <f32>t;
2309
+ }
2310
+
2311
+ // @ts-ignore: decorator
2312
+ @inline
2313
+ export function ceil(x: f32): f32 {
2314
+ return builtin_ceil<f32>(x);
2315
+ }
2316
+
2317
+ export function clz32(x: f32): f32 {
2318
+ if (!isFinite(x)) return 32;
2319
+ return <f32>builtin_clz(dtoi32(x));
2320
+ }
2321
+
2322
+ export function cos(x: f32): f32 {
2323
+ // see: musl/src/math/cosf.c
2324
+ const c1pio2 = reinterpret<f64>(0x3ff921fb54442d18), // M_PI_2 * 1
2325
+ c2pio2 = reinterpret<f64>(0x400921fb54442d18), // M_PI_2 * 2
2326
+ c3pio2 = reinterpret<f64>(0x4012d97c7f3321d2), // M_PI_2 * 3
2327
+ c4pio2 = reinterpret<f64>(0x401921fb54442d18); // M_PI_2 * 4
2328
+
2329
+ let ux = reinterpret<u32>(x);
2330
+ let sign = ux >> 31;
2331
+ ux &= 0x7fffffff;
2332
+
2333
+ if (ux <= 0x3f490fda) {
2334
+ // |x| ~<= π/4
2335
+ if (ux < 0x39800000) {
2336
+ // |x| < 2**-12
2337
+ // raise inexact if x != 0
2338
+ return 1;
2339
+ }
2340
+ return cos_kernf(x);
2341
+ }
2342
+
2343
+ if (ASC_SHRINK_LEVEL < 1) {
2344
+ if (ux <= 0x407b53d1) {
2345
+ // |x| ~<= 5π/4
2346
+ if (ux > 0x4016cbe3) {
2347
+ // |x| ~> 3π/4
2348
+ return -cos_kernf(sign ? x + c2pio2 : x - c2pio2);
2349
+ } else {
2350
+ return sign ? sin_kernf(x + c1pio2) : sin_kernf(c1pio2 - x);
2351
+ }
2352
+ }
2353
+ if (ux <= 0x40e231d5) {
2354
+ // |x| ~<= 9π/4
2355
+ if (ux > 0x40afeddf) {
2356
+ // |x| ~> 7π/4
2357
+ return cos_kernf(sign ? x + c4pio2 : x - c4pio2);
2358
+ } else {
2359
+ return sign ? sin_kernf(-x - c3pio2) : sin_kernf(x - c3pio2);
2360
+ }
2361
+ }
2362
+ }
2363
+
2364
+ // cos(Inf or NaN) is NaN
2365
+ if (ux >= 0x7f800000) return x - x;
2366
+
2367
+ // general argument reduction needed
2368
+ let n = rempio2f(x, ux, sign);
2369
+ let y = rempio2f_y;
2370
+
2371
+ let t = n & 1 ? sin_kernf(y) : cos_kernf(y);
2372
+ return (n + 1) & 2 ? -t : t;
2373
+ }
2374
+
2375
+ export function cosh(x: f32): f32 {
2376
+ // see: musl/src/math/coshf.c
2377
+ let u = reinterpret<u32>(x);
2378
+ u &= 0x7fffffff;
2379
+ x = reinterpret<f32>(u);
2380
+ if (u < 0x3f317217) {
2381
+ if (u < 0x3f800000 - (12 << 23)) return 1;
2382
+ let t = expm1(x);
2383
+ // return 1 + t * t / (2 * (1 + t));
2384
+ return 1 + (t * t) / (2 + 2 * t);
2385
+ }
2386
+ if (u < 0x42b17217) {
2387
+ let t = exp(x);
2388
+ // return 0.5 * (t + 1 / t);
2389
+ return 0.5 * t + 0.5 / t;
2390
+ }
2391
+ return expo2f(x, 1);
2392
+ }
2393
+
2394
+ // @ts-ignore: decorator
2395
+ @inline
2396
+ export function floor(x: f32): f32 {
2397
+ return builtin_floor<f32>(x);
2398
+ }
2399
+
2400
+ export function exp(x: f32): f32 {
2401
+ // see: musl/src/math/expf.c and SUN COPYRIGHT NOTICE above
2402
+ if (ASC_SHRINK_LEVEL < 1) {
2403
+ return expf_lut(x);
2404
+ } else {
2405
+ const ln2hi = reinterpret<f32>(0x3f317200), // 6.9314575195e-1f
2406
+ ln2lo = reinterpret<f32>(0x35bfbe8e), // 1.4286067653e-6f
2407
+ invln2 = reinterpret<f32>(0x3fb8aa3b), // 1.4426950216e+0f
2408
+ P1 = reinterpret<f32>(0x3e2aaa8f), // 1.6666625440e-1f
2409
+ P2 = reinterpret<f32>(0xbb355215), // -2.7667332906e-3f
2410
+ Ox1p127f = reinterpret<f32>(0x7f000000); // 0x1p+127f
2411
+
2412
+ let hx = reinterpret<u32>(x);
2413
+ let sign = hx >> 31;
2414
+ hx &= 0x7fffffff;
2415
+ if (hx >= 0x42aeac50) {
2416
+ if (hx > 0x7f800000) return x; // NaN
2417
+ if (hx >= 0x42b17218) {
2418
+ if (!sign) return x * Ox1p127f;
2419
+ else if (hx >= 0x42cff1b5) return 0;
2420
+ }
2421
+ }
2422
+ let hi: f32, lo: f32;
2423
+ let k: i32;
2424
+ if (hx > 0x3eb17218) {
2425
+ if (hx > 0x3f851592) {
2426
+ k = i32(invln2 * x + builtin_copysign<f32>(0.5, x));
2427
+ } else {
2428
+ k = 1 - (sign << 1);
2429
+ }
2430
+ hi = x - <f32>k * ln2hi;
2431
+ lo = <f32>k * ln2lo;
2432
+ x = hi - lo;
2433
+ } else if (hx > 0x39000000) {
2434
+ k = 0;
2435
+ hi = x;
2436
+ lo = 0;
2437
+ } else {
2438
+ return 1 + x;
2439
+ }
2440
+ let xx = x * x;
2441
+ let c = x - xx * (P1 + xx * P2);
2442
+ let y: f32 = 1 + ((x * c) / (2 - c) - lo + hi);
2443
+ return k == 0 ? y : scalbn(y, k);
2444
+ }
2445
+ }
2446
+
2447
+ export function exp2(x: f32): f32 {
2448
+ return exp2f_lut(x);
2449
+ }
2450
+
2451
+ export function expm1(x: f32): f32 {
2452
+ // see: musl/src/math/expm1f.c and SUN COPYRIGHT NOTICE above
2453
+ const ln2_hi = reinterpret<f32>(0x3f317180), // 6.9313812256e-01f
2454
+ ln2_lo = reinterpret<f32>(0x3717f7d1), // 9.0580006145e-06f
2455
+ invln2 = reinterpret<f32>(0x3fb8aa3b), // 1.4426950216e+00f
2456
+ Q1 = reinterpret<f32>(0xbd088868), // -3.3333212137e-02f
2457
+ Q2 = reinterpret<f32>(0x3acf3010), // 1.5807170421e-03f
2458
+ Ox1p127f = reinterpret<f32>(0x7f000000); // 0x1p+127f
2459
+
2460
+ let u = reinterpret<u32>(x);
2461
+ let hx = u & 0x7fffffff;
2462
+ let sign = u >> 31;
2463
+ if (hx >= 0x4195b844) {
2464
+ if (hx > 0x7f800000) return x;
2465
+ if (sign) return -1;
2466
+ if (hx > 0x42b17217) {
2467
+ // x > log(FLT_MAX)
2468
+ x *= Ox1p127f;
2469
+ return x;
2470
+ }
2471
+ }
2472
+ let c: f32 = 0.0,
2473
+ t: f32,
2474
+ k: i32;
2475
+ if (hx > 0x3eb17218) {
2476
+ k = select<i32>(1 - (sign << 1), i32(invln2 * x + builtin_copysign<f32>(0.5, x)), hx < 0x3f851592);
2477
+ t = <f32>k;
2478
+ let hi = x - t * ln2_hi;
2479
+ let lo = t * ln2_lo;
2480
+ x = hi - lo;
2481
+ c = hi - x - lo;
2482
+ } else if (hx < 0x33000000) {
2483
+ return x;
2484
+ } else k = 0;
2485
+ let hfx: f32 = 0.5 * x;
2486
+ let hxs: f32 = x * hfx;
2487
+ let r1: f32 = 1.0 + hxs * (Q1 + hxs * Q2);
2488
+ t = 3.0 - r1 * hfx;
2489
+ let e = hxs * ((r1 - t) / (6.0 - x * t));
2490
+ if (k == 0) return x - (x * e - hxs);
2491
+ e = x * (e - c) - c;
2492
+ e -= hxs;
2493
+ if (k == -1) return 0.5 * (x - e) - 0.5;
2494
+ if (k == 1) {
2495
+ if (x < -0.25) return -2.0 * (e - (x + 0.5));
2496
+ return 1.0 + 2.0 * (x - e);
2497
+ }
2498
+ u = (0x7f + k) << 23;
2499
+ let twopk = reinterpret<f32>(u);
2500
+ let y: f32;
2501
+ if (k < 0 || k > 56) {
2502
+ y = x - e + 1.0;
2503
+ if (k == 128) y = y * 2.0 * Ox1p127f;
2504
+ else y = y * twopk;
2505
+ return y - 1.0;
2506
+ }
2507
+ u = (0x7f - k) << 23;
2508
+ y = reinterpret<f32>(u);
2509
+ if (k < 20) y = 1 - y - e;
2510
+ else y = 1 - (e + y);
2511
+ return (x + y) * twopk;
2512
+ }
2513
+
2514
+ // @ts-ignore: decorator
2515
+ @inline
2516
+ export function fround(x: f32): f32 {
2517
+ return x;
2518
+ }
2519
+
2520
+ export function hypot(x: f32, y: f32): f32 {
2521
+ // see: musl/src/math/hypotf.c
2522
+ const Ox1p90f = reinterpret<f32>(0x6c800000),
2523
+ Ox1p_90f = reinterpret<f32>(0x12800000);
2524
+
2525
+ let ux = reinterpret<u32>(x);
2526
+ let uy = reinterpret<u32>(y);
2527
+ ux &= 0x7fffffff;
2528
+ uy &= 0x7fffffff;
2529
+ if (ux < uy) {
2530
+ let ut = ux;
2531
+ ux = uy;
2532
+ uy = ut;
2533
+ }
2534
+ x = reinterpret<f32>(ux);
2535
+ y = reinterpret<f32>(uy);
2536
+ if (uy == 0xff << 23) return y;
2537
+ if (ux >= 0xff << 23 || uy == 0 || ux - uy >= 25 << 23) return x + y;
2538
+ let z: f32 = 1;
2539
+ if (ux >= (0x7f + 60) << 23) {
2540
+ z = Ox1p90f;
2541
+ x *= Ox1p_90f;
2542
+ y *= Ox1p_90f;
2543
+ } else if (uy < (0x7f - 60) << 23) {
2544
+ z = Ox1p_90f;
2545
+ x *= Ox1p90f;
2546
+ y *= Ox1p90f;
2547
+ }
2548
+ return z * builtin_sqrt<f32>(f32(<f64>x * x + <f64>y * y));
2549
+ }
2550
+
2551
+ // @ts-ignore: decorator
2552
+ @inline
2553
+ export function imul(x: f32, y: f32): f32 {
2554
+ /*
2555
+ * Wasm (MVP) and JS have different approaches for double->int conversions.
2556
+ *
2557
+ * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
2558
+ * our float-point arguments before actual convertion to integers.
2559
+ */
2560
+ if (!isFinite(x + y)) return 0;
2561
+ return <f32>(dtoi32(x) * dtoi32(y));
2562
+ }
2563
+
2564
+ export function log(x: f32): f32 {
2565
+ // see: musl/src/math/logf.c and SUN COPYRIGHT NOTICE above
2566
+ if (ASC_SHRINK_LEVEL < 1) {
2567
+ return logf_lut(x);
2568
+ } else {
2569
+ const ln2_hi = reinterpret<f32>(0x3f317180), // 6.9313812256e-01f
2570
+ ln2_lo = reinterpret<f32>(0x3717f7d1), // 9.0580006145e-06f
2571
+ Lg1 = reinterpret<f32>(0x3f2aaaaa), // 0xaaaaaa.0p-24f
2572
+ Lg2 = reinterpret<f32>(0x3eccce13), // 0xccce13.0p-25f
2573
+ Lg3 = reinterpret<f32>(0x3e91e9ee), // 0x91e9ee.0p-25f
2574
+ Lg4 = reinterpret<f32>(0x3e789e26), // 0xf89e26.0p-26f
2575
+ Ox1p25f = reinterpret<f32>(0x4c000000);
2576
+
2577
+ let u = reinterpret<u32>(x);
2578
+ let k = 0;
2579
+ let sign = u >> 31;
2580
+ if (sign || u < 0x00800000) {
2581
+ if (u << 1 == 0) return -1 / (x * x);
2582
+ if (sign) return (x - x) / 0;
2583
+ k -= 25;
2584
+ x *= Ox1p25f;
2585
+ u = reinterpret<u32>(x);
2586
+ } else if (u >= 0x7f800000) {
2587
+ return x;
2588
+ } else if (u == 0x3f800000) {
2589
+ return 0;
2590
+ }
2591
+ u += 0x3f800000 - 0x3f3504f3;
2592
+ k += i32(u >> 23) - 0x7f;
2593
+ u = (u & 0x007fffff) + 0x3f3504f3;
2594
+ x = reinterpret<f32>(u);
2595
+ let f = x - 1.0;
2596
+ let s = f / (2.0 + f);
2597
+ let z = s * s;
2598
+ let w = z * z;
2599
+ let t1 = w * (Lg2 + w * Lg4);
2600
+ let t2 = z * (Lg1 + w * Lg3);
2601
+ let r = t2 + t1;
2602
+ let hfsq = <f32>0.5 * f * f;
2603
+ let dk = <f32>k;
2604
+ return s * (hfsq + r) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
2605
+ }
2606
+ }
2607
+
2608
+ export function log10(x: f32): f32 {
2609
+ // see: musl/src/math/log10f.c and SUN COPYRIGHT NOTICE above
2610
+ const ivln10hi = reinterpret<f32>(0x3ede6000), // 4.3432617188e-01f
2611
+ ivln10lo = reinterpret<f32>(0xb804ead9), // -3.1689971365e-05f
2612
+ log10_2hi = reinterpret<f32>(0x3e9a2080), // 3.0102920532e-01f
2613
+ log10_2lo = reinterpret<f32>(0x355427db), // 7.9034151668e-07f
2614
+ Lg1 = reinterpret<f32>(0x3f2aaaaa), // 0xaaaaaa.0p-24f, 0.66666662693f
2615
+ Lg2 = reinterpret<f32>(0x3eccce13), // 0xccce13.0p-25f, 0.40000972152f
2616
+ Lg3 = reinterpret<f32>(0x3e91e9ee), // 0x91e9ee.0p-25f, 0.28498786688f
2617
+ Lg4 = reinterpret<f32>(0x3e789e26), // 0xf89e26.0p-26f, 0.24279078841f
2618
+ Ox1p25f = reinterpret<f32>(0x4c000000); // 0x1p25f
2619
+
2620
+ let ux = reinterpret<u32>(x);
2621
+ let k = 0;
2622
+ let sign = ux >> 31;
2623
+ if (sign || ux < 0x00800000) {
2624
+ if (ux << 1 == 0) return -1 / (x * x);
2625
+ if (sign) return (x - x) / 0.0;
2626
+ k -= 25;
2627
+ x *= Ox1p25f;
2628
+ ux = reinterpret<u32>(x);
2629
+ } else if (ux >= 0x7f800000) {
2630
+ return x;
2631
+ } else if (ux == 0x3f800000) {
2632
+ return 0;
2633
+ }
2634
+ ux += 0x3f800000 - 0x3f3504f3;
2635
+ k += i32(ux >> 23) - 0x7f;
2636
+ ux = (ux & 0x007fffff) + 0x3f3504f3;
2637
+ x = reinterpret<f32>(ux);
2638
+ let f = x - 1.0;
2639
+ let s = f / (2.0 + f);
2640
+ let z = s * s;
2641
+ let w = z * z;
2642
+ let t1 = w * (Lg2 + w * Lg4);
2643
+ let t2 = z * (Lg1 + w * Lg3);
2644
+ let r = t2 + t1;
2645
+ let hfsq: f32 = 0.5 * f * f;
2646
+ let hi = f - hfsq;
2647
+ ux = reinterpret<u32>(hi);
2648
+ ux &= 0xfffff000;
2649
+ hi = reinterpret<f32>(ux);
2650
+ let lo = f - hi - hfsq + s * (hfsq + r);
2651
+ let dk = <f32>k;
2652
+ return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
2653
+ }
2654
+
2655
+ export function log1p(x: f32): f32 {
2656
+ // see: musl/src/math/log1pf.c and SUN COPYRIGHT NOTICE above
2657
+ const ln2_hi = reinterpret<f32>(0x3f317180), // 6.9313812256e-01
2658
+ ln2_lo = reinterpret<f32>(0x3717f7d1), // 9.0580006145e-06
2659
+ Lg1 = reinterpret<f32>(0x3f2aaaaa), // 0xaaaaaa.0p-24f, 0.66666662693f
2660
+ Lg2 = reinterpret<f32>(0x3eccce13), // 0xccce13.0p-25f, 0.40000972152f
2661
+ Lg3 = reinterpret<f32>(0x3e91e9ee), // 0x91e9ee.0p-25f, 0.28498786688f
2662
+ Lg4 = reinterpret<f32>(0x3e789e26); // 0xf89e26.0p-26f, 0.24279078841f
2663
+
2664
+ let ix = reinterpret<u32>(x);
2665
+ let c: f32 = 0;
2666
+ let f: f32 = 0;
2667
+ let k = 1;
2668
+ if (ix < 0x3ed413d0 || bool(ix >> 31)) {
2669
+ if (ix >= 0xbf800000) {
2670
+ if (x == -1) return x / 0.0;
2671
+ return (x - x) / 0.0;
2672
+ }
2673
+ if (ix << 1 < 0x33800000 << 1) return x;
2674
+ if (ix <= 0xbe95f619) {
2675
+ k = 0;
2676
+ c = 0;
2677
+ f = x;
2678
+ }
2679
+ } else if (ix >= 0x7f800000) return x;
2680
+ if (k) {
2681
+ let uf: f32 = 1 + x;
2682
+ let iu = reinterpret<u32>(uf);
2683
+ iu += 0x3f800000 - 0x3f3504f3;
2684
+ k = i32(iu >> 23) - 0x7f;
2685
+ if (k < 25) {
2686
+ c = k >= 2 ? 1 - (uf - x) : x - (uf - 1);
2687
+ c /= uf;
2688
+ } else c = 0;
2689
+ iu = (iu & 0x007fffff) + 0x3f3504f3;
2690
+ f = reinterpret<f32>(iu) - 1;
2691
+ }
2692
+ let s = f / (2.0 + f);
2693
+ let z = s * s;
2694
+ let w = z * z;
2695
+ let t1 = w * (Lg2 + w * Lg4);
2696
+ let t2 = z * (Lg1 + w * Lg3);
2697
+ let r = t2 + t1;
2698
+ let hfsq: f32 = 0.5 * f * f;
2699
+ let dk = <f32>k;
2700
+ return s * (hfsq + r) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
2701
+ }
2702
+
2703
+ export function log2(x: f32): f32 {
2704
+ // see: musl/src/math/log2f.c and SUN COPYRIGHT NOTICE above
2705
+ if (ASC_SHRINK_LEVEL < 1) {
2706
+ return log2f_lut(x);
2707
+ } else {
2708
+ const ivln2hi = reinterpret<f32>(0x3fb8b000), // 1.4428710938e+00f
2709
+ ivln2lo = reinterpret<f32>(0xb9389ad4), // -1.7605285393e-04
2710
+ Lg1 = reinterpret<f32>(0x3f2aaaaa), // 0xaaaaaa.0p-24f, 0.66666662693f
2711
+ Lg2 = reinterpret<f32>(0x3eccce13), // 0xccce13.0p-25f, 0.40000972152f
2712
+ Lg3 = reinterpret<f32>(0x3e91e9ee), // 0x91e9ee.0p-25f, 0.28498786688f
2713
+ Lg4 = reinterpret<f32>(0x3e789e26), // 0xf89e26.0p-26f, 0.24279078841f
2714
+ Ox1p25f = reinterpret<f32>(0x4c000000); // 0x1p25f
2715
+
2716
+ let ux = reinterpret<u32>(x);
2717
+ let k = 0;
2718
+ let sign = ux >> 31;
2719
+ if (sign || ux < 0x00800000) {
2720
+ if (ux << 1 == 0) return -1 / (x * x);
2721
+ if (sign) return (x - x) / 0.0;
2722
+ k -= 25;
2723
+ x *= Ox1p25f;
2724
+ ux = reinterpret<u32>(x);
2725
+ } else if (ux >= 0x7f800000) {
2726
+ return x;
2727
+ } else if (ux == 0x3f800000) {
2728
+ return 0;
2729
+ }
2730
+ ux += 0x3f800000 - 0x3f3504f3;
2731
+ k += i32(ux >> 23) - 0x7f;
2732
+ ux = (ux & 0x007fffff) + 0x3f3504f3;
2733
+ x = reinterpret<f32>(ux);
2734
+ let f = x - 1.0;
2735
+ let s = f / (2.0 + f);
2736
+ let z = s * s;
2737
+ let w = z * z;
2738
+ let t1 = w * (Lg2 + w * Lg4);
2739
+ let t2 = z * (Lg1 + w * Lg3);
2740
+ let r = t2 + t1;
2741
+ let hfsq: f32 = 0.5 * f * f;
2742
+ let hi = f - hfsq;
2743
+ let u = reinterpret<u32>(hi);
2744
+ u &= 0xfffff000;
2745
+ hi = reinterpret<f32>(u);
2746
+ let lo: f32 = f - hi - hfsq + s * (hfsq + r);
2747
+ let dk = <f32>k;
2748
+ return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + dk;
2749
+ }
2750
+ }
2751
+
2752
+ // @ts-ignore: decorator
2753
+ @inline
2754
+ export function max(value1: f32, value2: f32): f32 {
2755
+ return builtin_max<f32>(value1, value2);
2756
+ }
2757
+
2758
+ // @ts-ignore: decorator
2759
+ @inline
2760
+ export function min(value1: f32, value2: f32): f32 {
2761
+ return builtin_min<f32>(value1, value2);
2762
+ }
2763
+
2764
+ export function pow(x: f32, y: f32): f32 {
2765
+ // TODO: remove this fast pathes after introduced own mid-end IR with "stdlib call simplify" transforms
2766
+ if (builtin_abs<f32>(y) <= 2) {
2767
+ if (y == 2.0) return x * x;
2768
+ if (y == 0.5) {
2769
+ return select<f32>(builtin_abs<f32>(builtin_sqrt<f32>(x)), Infinity, x != -Infinity);
2770
+ }
2771
+ if (y == -1.0) return 1 / x;
2772
+ if (y == 1.0) return x;
2773
+ if (y == 0.0) return 1.0;
2774
+ }
2775
+ if (ASC_SHRINK_LEVEL < 1) {
2776
+ // see: musl/src/math/powf.c
2777
+ return powf_lut(x, y);
2778
+ } else {
2779
+ // based on: jdh8/metallic/src/math/float/powf.c
2780
+ if (y == 0) return 1;
2781
+ // @ts-ignore: cast
2782
+ if (isNaN(x) | isNaN(y)) {
2783
+ return NaN;
2784
+ }
2785
+ let sign: u32 = 0;
2786
+ let uy = reinterpret<u32>(y);
2787
+ let ux = reinterpret<u32>(x);
2788
+ let sx = ux >> 31;
2789
+ ux &= 0x7fffffff;
2790
+ if (sx && nearest(y) == y) {
2791
+ x = -x;
2792
+ sx = 0;
2793
+ sign = u32(nearest(y * 0.5) != y * 0.5) << 31;
2794
+ }
2795
+ let m: u32;
2796
+ if (ux == 0x3f800000) {
2797
+ // x == 1
2798
+ m = sx | u32((uy & 0x7fffffff) == 0x7f800000) ? 0x7fc00000 : 0x3f800000;
2799
+ } else if (ux == 0) {
2800
+ m = <i32>uy < 0 ? 0x7f800000 : 0;
2801
+ } else if (ux == 0x7f800000) {
2802
+ m = <i32>uy < 0 ? 0 : 0x7f800000;
2803
+ } else if (sx) {
2804
+ m = 0x7fc00000;
2805
+ } else {
2806
+ m = reinterpret<u32>(<f32>exp2f(<f64>y * log2f(x)));
2807
+ }
2808
+ return reinterpret<f32>(m | sign);
2809
+ }
2810
+ }
2811
+
2812
+ // @ts-ignore: decorator
2813
+ @inline
2814
+ export function seedRandom(value: i64): void {
2815
+ NativeMath.seedRandom(value);
2816
+ }
2817
+
2818
+ // Using xoroshiro64starstar from http://xoshiro.di.unimi.it/xoroshiro64starstar.c
2819
+ export function random(): f32 {
2820
+ if (!random_seeded) seedRandom(reinterpret<i64>(seed()));
2821
+
2822
+ let s0 = random_state0_32;
2823
+ let s1 = random_state1_32;
2824
+ let r = rotl<u32>(s0 * 0x9e3779bb, 5) * 5;
2825
+
2826
+ s1 ^= s0;
2827
+ random_state0_32 = rotl<u32>(s0, 26) ^ s1 ^ (s1 << 9);
2828
+ random_state1_32 = rotl<u32>(s1, 13);
2829
+
2830
+ return reinterpret<f32>((r >> 9) | (127 << 23)) - 1.0;
2831
+ }
2832
+
2833
+ export function round(x: f32): f32 {
2834
+ if (ASC_SHRINK_LEVEL > 0) {
2835
+ return builtin_ceil<f32>(x) - f32(builtin_ceil<f32>(x) - 0.5 > x);
2836
+ } else {
2837
+ let roundUp = builtin_ceil<f32>(x);
2838
+ return select<f32>(roundUp, roundUp - 1.0, roundUp - 0.5 <= x);
2839
+ }
2840
+ }
2841
+
2842
+ export function sign(x: f32): f32 {
2843
+ if (ASC_SHRINK_LEVEL > 0) {
2844
+ return select<f32>(builtin_copysign<f32>(1, x), x, builtin_abs(x) > 0);
2845
+ } else {
2846
+ return select<f32>(1, select<f32>(-1, x, x < 0), x > 0);
2847
+ }
2848
+ }
2849
+
2850
+ // @ts-ignore: decorator
2851
+ @inline
2852
+ export function signbit(x: f32): bool {
2853
+ return <bool>(reinterpret<u32>(x) >>> 31);
2854
+ }
2855
+
2856
+ export function sin(x: f32): f32 {
2857
+ // see: musl/src/math/sinf.c
2858
+ const s1pio2 = reinterpret<f64>(0x3ff921fb54442d18), // M_PI_2 * 1
2859
+ s2pio2 = reinterpret<f64>(0x400921fb54442d18), // M_PI_2 * 2
2860
+ s3pio2 = reinterpret<f64>(0x4012d97c7f3321d2), // M_PI_2 * 3
2861
+ s4pio2 = reinterpret<f64>(0x401921fb54442d18); // M_PI_2 * 4
2862
+
2863
+ let ux = reinterpret<u32>(x);
2864
+ let sign = ux >> 31;
2865
+ ux &= 0x7fffffff;
2866
+
2867
+ if (ux <= 0x3f490fda) {
2868
+ // |x| ~<= π/4
2869
+ if (ux < 0x39800000) {
2870
+ // |x| < 2**-12
2871
+ return x;
2872
+ }
2873
+ return sin_kernf(x);
2874
+ }
2875
+
2876
+ if (ASC_SHRINK_LEVEL < 1) {
2877
+ if (ux <= 0x407b53d1) {
2878
+ // |x| ~<= 5π/4
2879
+ if (ux <= 0x4016cbe3) {
2880
+ // |x| ~<= 3π/4
2881
+ return sign ? -cos_kernf(x + s1pio2) : cos_kernf(x - s1pio2);
2882
+ }
2883
+ return sin_kernf(-(sign ? x + s2pio2 : x - s2pio2));
2884
+ }
2885
+
2886
+ if (ux <= 0x40e231d5) {
2887
+ // |x| ~<= 9π/4
2888
+ if (ux <= 0x40afeddf) {
2889
+ // |x| ~<= 7π/4
2890
+ return sign ? cos_kernf(x + s3pio2) : -cos_kernf(x - s3pio2);
2891
+ }
2892
+ return sin_kernf(sign ? x + s4pio2 : x - s4pio2);
2893
+ }
2894
+ }
2895
+
2896
+ // sin(Inf or NaN) is NaN
2897
+ if (ux >= 0x7f800000) return x - x;
2898
+
2899
+ let n = rempio2f(x, ux, sign);
2900
+ let y = rempio2f_y;
2901
+
2902
+ let t = n & 1 ? cos_kernf(y) : sin_kernf(y);
2903
+ return n & 2 ? -t : t;
2904
+ }
2905
+
2906
+ export function sinh(x: f32): f32 {
2907
+ // see: musl/src/math/sinhf.c
2908
+ let u = reinterpret<u32>(x) & 0x7fffffff;
2909
+ let a = reinterpret<f32>(u);
2910
+ let h = builtin_copysign<f32>(0.5, x);
2911
+ if (u < 0x42b17217) {
2912
+ let t = expm1(a);
2913
+ if (u < 0x3f800000) {
2914
+ if (u < 0x3f800000 - (12 << 23)) return x;
2915
+ return h * (2 * t - (t * t) / (t + 1));
2916
+ }
2917
+ return h * (t + t / (t + 1));
2918
+ }
2919
+ return expo2f(a, 2 * h);
2920
+ }
2921
+
2922
+ // @ts-ignore: decorator
2923
+ @inline
2924
+ export function sqrt(x: f32): f32 {
2925
+ return builtin_sqrt<f32>(x);
2926
+ }
2927
+
2928
+ export function tan(x: f32): f32 {
2929
+ // see: musl/src/math/tanf.c
2930
+ const t1pio2 = reinterpret<f64>(0x3ff921fb54442d18), // 1 * M_PI_2
2931
+ t2pio2 = reinterpret<f64>(0x400921fb54442d18), // 2 * M_PI_2
2932
+ t3pio2 = reinterpret<f64>(0x4012d97c7f3321d2), // 3 * M_PI_2
2933
+ t4pio2 = reinterpret<f64>(0x401921fb54442d18); // 4 * M_PI_2
2934
+
2935
+ let ux = reinterpret<u32>(x);
2936
+ let sign = ux >> 31;
2937
+ ux &= 0x7fffffff;
2938
+
2939
+ if (ux <= 0x3f490fda) {
2940
+ // |x| ~<= π/4
2941
+ if (ux < 0x39800000) {
2942
+ // |x| < 2**-12
2943
+ return x;
2944
+ }
2945
+ return tan_kernf(x, 0);
2946
+ }
2947
+
2948
+ if (ASC_SHRINK_LEVEL < 1) {
2949
+ if (ux <= 0x407b53d1) {
2950
+ // |x| ~<= 5π/4
2951
+ if (ux <= 0x4016cbe3) {
2952
+ // |x| ~<= 3π/4
2953
+ return tan_kernf(sign ? x + t1pio2 : x - t1pio2, 1);
2954
+ } else {
2955
+ return tan_kernf(sign ? x + t2pio2 : x - t2pio2, 0);
2956
+ }
2957
+ }
2958
+ if (ux <= 0x40e231d5) {
2959
+ // |x| ~<= 9π/4
2960
+ if (ux <= 0x40afeddf) {
2961
+ // |x| ~<= 7π/4
2962
+ return tan_kernf(sign ? x + t3pio2 : x - t3pio2, 1);
2963
+ } else {
2964
+ return tan_kernf(sign ? x + t4pio2 : x - t4pio2, 0);
2965
+ }
2966
+ }
2967
+ }
2968
+
2969
+ // tan(Inf or NaN) is NaN
2970
+ if (ux >= 0x7f800000) return x - x;
2971
+
2972
+ // argument reduction
2973
+ let n = rempio2f(x, ux, sign);
2974
+ let y = rempio2f_y;
2975
+ return tan_kernf(y, n & 1);
2976
+ }
2977
+
2978
+ export function tanh(x: f32): f32 {
2979
+ // see: musl/src/math/tanhf.c
2980
+ let u = reinterpret<u32>(x);
2981
+ u &= 0x7fffffff;
2982
+ let y = reinterpret<f32>(u);
2983
+ let t: f32;
2984
+ if (u > 0x3f0c9f54) {
2985
+ if (u > 0x41200000) t = 1 + 0 / y;
2986
+ else {
2987
+ t = expm1(2 * y);
2988
+ t = 1 - 2 / (t + 2);
2989
+ }
2990
+ } else if (u > 0x3e82c578) {
2991
+ t = expm1(2 * y);
2992
+ t = t / (t + 2);
2993
+ } else if (u >= 0x00800000) {
2994
+ t = expm1(-2 * y);
2995
+ t = -t / (t + 2);
2996
+ } else t = y;
2997
+ return builtin_copysign<f32>(t, x);
2998
+ }
2999
+
3000
+ // @ts-ignore: decorator
3001
+ @inline
3002
+ export function trunc(x: f32): f32 {
3003
+ return builtin_trunc<f32>(x);
3004
+ }
3005
+
3006
+ export function scalbn(x: f32, n: i32): f32 {
3007
+ // see: https://git.musl-libc.org/cgit/musl/tree/src/math/scalbnf.c
3008
+ const Ox1p24f = reinterpret<f32>(0x4b800000),
3009
+ Ox1p127f = reinterpret<f32>(0x7f000000),
3010
+ Ox1p_126f = reinterpret<f32>(0x00800000);
3011
+
3012
+ let y = x;
3013
+ if (n > 127) {
3014
+ y *= Ox1p127f;
3015
+ n -= 127;
3016
+ if (n > 127) {
3017
+ y *= Ox1p127f;
3018
+ n = builtin_min<i32>(n - 127, 127);
3019
+ }
3020
+ } else if (n < -126) {
3021
+ y *= Ox1p_126f * Ox1p24f;
3022
+ n += 126 - 24;
3023
+ if (n < -126) {
3024
+ y *= Ox1p_126f * Ox1p24f;
3025
+ n = builtin_max<i32>(n + 126 - 24, -126);
3026
+ }
3027
+ }
3028
+ return y * reinterpret<f32>((<u32>(0x7f + n)) << 23);
3029
+ }
3030
+
3031
+ export function mod(x: f32, y: f32): f32 {
3032
+ // see: musl/src/math/fmodf.c
3033
+ if (builtin_abs<f32>(y) == 1.0) {
3034
+ // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))
3035
+ // TODO: move this rule to compiler's optimization pass.
3036
+ // It could be apply for any x % C_pot, where "C_pot" is pow of two const.
3037
+ return builtin_copysign<f32>(x - builtin_trunc<f32>(x), x);
3038
+ }
3039
+ let ux = reinterpret<u32>(x);
3040
+ let uy = reinterpret<u32>(y);
3041
+ let ex = i32((ux >> 23) & 0xff);
3042
+ let ey = i32((uy >> 23) & 0xff);
3043
+ let sm = ux & 0x80000000;
3044
+ let uy1 = uy << 1;
3045
+ if (uy1 == 0 || ex == 0xff || isNaN<f32>(y)) {
3046
+ let m = x * y;
3047
+ return m / m;
3048
+ }
3049
+ let ux1 = ux << 1;
3050
+ if (ux1 <= uy1) {
3051
+ return x * f32(ux1 != uy1);
3052
+ }
3053
+ if (!ex) {
3054
+ ex -= builtin_clz<u32>(ux << 9);
3055
+ ux <<= 1 - ex;
3056
+ } else {
3057
+ ux &= (<u32>-1) >> 9;
3058
+ ux |= 1 << 23;
3059
+ }
3060
+ if (!ey) {
3061
+ ey -= builtin_clz<u32>(uy << 9);
3062
+ uy <<= 1 - ey;
3063
+ } else {
3064
+ uy &= u32(-1) >> 9;
3065
+ uy |= 1 << 23;
3066
+ }
3067
+ while (ex > ey) {
3068
+ if (ux >= uy) {
3069
+ if (ux == uy) return 0 * x;
3070
+ ux -= uy;
3071
+ }
3072
+ ux <<= 1;
3073
+ --ex;
3074
+ }
3075
+ if (ux >= uy) {
3076
+ if (ux == uy) return 0 * x;
3077
+ ux -= uy;
3078
+ }
3079
+ // for (; !(ux >> 23); ux <<= 1) --ex;
3080
+ let shift = <i32>builtin_clz<u32>(ux << 8);
3081
+ ex -= shift;
3082
+ ux <<= shift;
3083
+ if (ex > 0) {
3084
+ ux -= 1 << 23;
3085
+ ux |= (<u32>ex) << 23;
3086
+ } else {
3087
+ ux >>= -ex + 1;
3088
+ }
3089
+ return reinterpret<f32>(ux | sm);
3090
+ }
3091
+
3092
+ export function rem(x: f32, y: f32): f32 {
3093
+ // see: musl/src/math/remquof.c
3094
+ let ux = reinterpret<u32>(x);
3095
+ let uy = reinterpret<u32>(y);
3096
+ let ex = i32((ux >> 23) & 0xff);
3097
+ let ey = i32((uy >> 23) & 0xff);
3098
+ let uxi = ux;
3099
+ if (uy << 1 == 0 || ex == 0xff || isNaN(y)) return (x * y) / (x * y);
3100
+ if (ux << 1 == 0) return x;
3101
+ if (!ex) {
3102
+ ex -= builtin_clz<u32>(uxi << 9);
3103
+ uxi <<= 1 - ex;
3104
+ } else {
3105
+ uxi &= u32(-1) >> 9;
3106
+ uxi |= 1 << 23;
3107
+ }
3108
+ if (!ey) {
3109
+ ey -= builtin_clz<u32>(uy << 9);
3110
+ uy <<= 1 - ey;
3111
+ } else {
3112
+ uy &= u32(-1) >> 9;
3113
+ uy |= 1 << 23;
3114
+ }
3115
+ let q = 0;
3116
+ do {
3117
+ if (ex < ey) {
3118
+ if (ex + 1 == ey) break; // goto end
3119
+ return x;
3120
+ }
3121
+ while (ex > ey) {
3122
+ if (uxi >= uy) {
3123
+ uxi -= uy;
3124
+ ++q;
3125
+ }
3126
+ uxi <<= 1;
3127
+ q <<= 1;
3128
+ --ex;
3129
+ }
3130
+ if (uxi >= uy) {
3131
+ uxi -= uy;
3132
+ ++q;
3133
+ }
3134
+ if (uxi == 0) ex = -30;
3135
+ else {
3136
+ let shift = builtin_clz<i32>(uxi << 8);
3137
+ ex -= shift;
3138
+ uxi <<= shift;
3139
+ }
3140
+ break;
3141
+ } while (false);
3142
+ // end:
3143
+ if (ex > 0) {
3144
+ uxi -= 1 << 23;
3145
+ uxi |= (<u32>ex) << 23;
3146
+ } else {
3147
+ uxi >>= -ex + 1;
3148
+ }
3149
+ x = reinterpret<f32>(uxi);
3150
+ y = builtin_abs<f32>(y);
3151
+ let x2 = x + x;
3152
+ if (ex == ey || (ex + 1 == ey && (<f32>x2 > y || (<f32>x2 == y && bool(q & 1))))) {
3153
+ x -= y;
3154
+ // q++;
3155
+ }
3156
+ return <i32>ux < 0 ? -x : x;
3157
+ }
3158
+
3159
+ export function sincos(x: f32): void {
3160
+ // see: musl/tree/src/math/sincosf.c
3161
+ const s1pio2 = reinterpret<f64>(0x3ff921fb54442d18), // 1 * M_PI_2
3162
+ s2pio2 = reinterpret<f64>(0x400921fb54442d18), // 2 * M_PI_2
3163
+ s3pio2 = reinterpret<f64>(0x4012d97c7f3321d2), // 3 * M_PI_2
3164
+ s4pio2 = reinterpret<f64>(0x401921fb54442d18); // 4 * M_PI_2
3165
+
3166
+ let ux = reinterpret<u32>(x);
3167
+ let sign = ux >> 31;
3168
+ ux &= 0x7fffffff;
3169
+
3170
+ if (ux <= 0x3f490fda) {
3171
+ // |x| ~<= π/4
3172
+ if (ux < 0x39800000) {
3173
+ // |x| < 2**-12
3174
+ sincos_sin = x;
3175
+ sincos_cos = 1;
3176
+ return;
3177
+ }
3178
+ sincos_sin = sin_kernf(x);
3179
+ sincos_cos = cos_kernf(x);
3180
+ return;
3181
+ }
3182
+ if (ASC_SHRINK_LEVEL < 1) {
3183
+ if (ux <= 0x407b53d1) {
3184
+ // |x| ~<= 5π/4
3185
+ if (ux <= 0x4016cbe3) {
3186
+ // |x| ~<= 3π/4
3187
+ if (sign) {
3188
+ sincos_sin = -cos_kernf(x + s1pio2);
3189
+ sincos_cos = sin_kernf(x + s1pio2);
3190
+ } else {
3191
+ sincos_sin = cos_kernf(s1pio2 - x);
3192
+ sincos_cos = sin_kernf(s1pio2 - x);
3193
+ }
3194
+ return;
3195
+ }
3196
+ // -sin(x + c) is not correct if x+c could be 0: -0 vs +0
3197
+ sincos_sin = -sin_kernf(sign ? x + s2pio2 : x - s2pio2);
3198
+ sincos_cos = -cos_kernf(sign ? x + s2pio2 : x - s2pio2);
3199
+ return;
3200
+ }
3201
+ if (ux <= 0x40e231d5) {
3202
+ // |x| ~<= 9π/4
3203
+ if (ux <= 0x40afeddf) {
3204
+ // |x| ~<= 7π/4
3205
+ if (sign) {
3206
+ sincos_sin = cos_kernf(x + s3pio2);
3207
+ sincos_cos = -sin_kernf(x + s3pio2);
3208
+ } else {
3209
+ sincos_sin = -cos_kernf(x - s3pio2);
3210
+ sincos_cos = sin_kernf(x - s3pio2);
3211
+ }
3212
+ return;
3213
+ }
3214
+ sincos_sin = sin_kernf(sign ? x + s4pio2 : x - s4pio2);
3215
+ sincos_cos = cos_kernf(sign ? x + s4pio2 : x - s4pio2);
3216
+ return;
3217
+ }
3218
+ }
3219
+ // sin(Inf or NaN) is NaN
3220
+ if (ux >= 0x7f800000) {
3221
+ let xx = x - x;
3222
+ sincos_sin = xx;
3223
+ sincos_cos = xx;
3224
+ return;
3225
+ }
3226
+ // general argument reduction needed
3227
+ let n = rempio2f(x, ux, sign);
3228
+ let y = rempio2f_y;
3229
+ let s = sin_kernf(y);
3230
+ let c = cos_kernf(y);
3231
+ let sin = s,
3232
+ cos = c;
3233
+ if (n & 1) {
3234
+ sin = c;
3235
+ cos = -s;
3236
+ }
3237
+ if (n & 2) {
3238
+ sin = -sin;
3239
+ cos = -cos;
3240
+ }
3241
+ sincos_sin = sin;
3242
+ sincos_cos = cos;
3243
+ }
3244
+ }
3245
+
3246
+ export function ipow32(x: i32, e: i32): i32 {
3247
+ let out = 1;
3248
+ if (ASC_SHRINK_LEVEL < 1) {
3249
+ if (x == 2) {
3250
+ return select<i32>(1 << e, 0, <u32>e < 32);
3251
+ }
3252
+ if (e <= 0) {
3253
+ if (x == -1) return select<i32>(-1, 1, e & 1);
3254
+ return i32(e == 0) | i32(x == 1);
3255
+ } else if (e == 1) return x;
3256
+ else if (e == 2) return x * x;
3257
+ else if (e < 32) {
3258
+ let log = 32 - clz(e);
3259
+ // 32 = 2 ^ 5, so need only five cases.
3260
+ // But some extra cases needs for properly overflowing
3261
+ switch (log) {
3262
+ case 5: {
3263
+ if (e & 1) out *= x;
3264
+ e >>>= 1;
3265
+ x *= x;
3266
+ }
3267
+ case 4: {
3268
+ if (e & 1) out *= x;
3269
+ e >>>= 1;
3270
+ x *= x;
3271
+ }
3272
+ case 3: {
3273
+ if (e & 1) out *= x;
3274
+ e >>>= 1;
3275
+ x *= x;
3276
+ }
3277
+ case 2: {
3278
+ if (e & 1) out *= x;
3279
+ e >>>= 1;
3280
+ x *= x;
3281
+ }
3282
+ case 1: {
3283
+ if (e & 1) out *= x;
3284
+ }
3285
+ }
3286
+ return out;
3287
+ }
3288
+ }
3289
+ while (e) {
3290
+ if (e & 1) out *= x;
3291
+ e >>>= 1;
3292
+ x *= x;
3293
+ }
3294
+ return out;
3295
+ }
3296
+
3297
+ export function ipow64(x: i64, e: i64): i64 {
3298
+ let out: i64 = 1;
3299
+ if (ASC_SHRINK_LEVEL < 1) {
3300
+ if (x == 2) {
3301
+ return select<i64>(1 << e, 0, <u64>e < 64);
3302
+ }
3303
+ if (e <= 0) {
3304
+ if (x == -1) return select<i64>(-1, 1, e & 1);
3305
+ return i64(e == 0) | i64(x == 1);
3306
+ } else if (e == 1) return x;
3307
+ else if (e == 2) return x * x;
3308
+ else if (e < 64) {
3309
+ let log = 64 - <i32>clz(e);
3310
+ // 64 = 2 ^ 6, so need only six cases.
3311
+ // But some extra cases needs for properly overflowing
3312
+ switch (log) {
3313
+ case 6: {
3314
+ if (e & 1) out *= x;
3315
+ e >>>= 1;
3316
+ x *= x;
3317
+ }
3318
+ case 5: {
3319
+ if (e & 1) out *= x;
3320
+ e >>>= 1;
3321
+ x *= x;
3322
+ }
3323
+ case 4: {
3324
+ if (e & 1) out *= x;
3325
+ e >>>= 1;
3326
+ x *= x;
3327
+ }
3328
+ case 3: {
3329
+ if (e & 1) out *= x;
3330
+ e >>>= 1;
3331
+ x *= x;
3332
+ }
3333
+ case 2: {
3334
+ if (e & 1) out *= x;
3335
+ e >>>= 1;
3336
+ x *= x;
3337
+ }
3338
+ case 1: {
3339
+ if (e & 1) out *= x;
3340
+ }
3341
+ }
3342
+ return out;
3343
+ }
3344
+ }
3345
+ while (e) {
3346
+ if (e & 1) out *= x;
3347
+ e >>>= 1;
3348
+ x *= x;
3349
+ }
3350
+ return out;
3351
+ }
3352
+
3353
+ /*
3354
+ TODO:
3355
+ In compile time if only exponent is constant we could replace ipow32/ipow64 by shortest addition chains
3356
+ which usually faster than exponentiation by squaring
3357
+
3358
+ for ipow32 and e < 32:
3359
+
3360
+ let b: i32, c: i32, d: i32, h: i32, k: i32, g: i32;
3361
+ switch (e) {
3362
+ case 1: return x;
3363
+ case 2: return x * x;
3364
+ case 3: return x * x * x;
3365
+ case 4: return (b = x * x) * b;
3366
+ case 5: return (b = x * x) * b * x;
3367
+ case 6: return (b = x * x) * b * b;
3368
+ case 7: return (b = x * x) * b * b * x;
3369
+ case 8: return (d = (b = x * x) * b) * d;
3370
+ case 9: return (c = x * x * x) * c * c;
3371
+ case 10: return (d = (b = x * x) * b) * d * b;
3372
+ case 11: return (d = (b = x * x) * b) * d * b * x;
3373
+ case 12: return (d = (b = x * x) * b) * d * d;
3374
+ case 13: return (d = (b = x * x) * b) * d * d * x;
3375
+ case 14: return (d = (b = x * x) * b) * d * d * b;
3376
+ case 15: return (k = (b = x * x) * b * x) * k * k;
3377
+ case 16: return (h = (d = (b = x * x) * b) * d) * h;
3378
+ case 17: return (h = (d = (b = x * x) * b) * d) * h * x;
3379
+ case 18: return (h = (d = (b = x * x) * b) * d * x) * h;
3380
+ case 19: return (h = (d = (b = x * x) * b) * d * x) * h * x;
3381
+ case 20: return (h = (k = (b = x * x) * b * x) * k) * h;
3382
+ case 21: return (h = (k = (b = x * x) * b * x) * k) * h * x;
3383
+ case 22: return (g = (h = (k = (b = x * x) * b * x) * k) * x) * g;
3384
+ case 23: return (h = (d = (c = (b = x * x) * x) * b) * d) * h * c;
3385
+ case 24: return (h = (d = (c = x * x * x) * c) * d) * h;
3386
+ case 25: return (h = (d = (c = x * x * x) * c) * d) * h * x;
3387
+ case 26: return (g = (h = (d = (c = x * x * x) * c) * d) * x) * g;
3388
+ case 27: return (h = (d = (c = x * x * x) * c) * d) * h * c;
3389
+ case 28: return (h = (d = (c = x * x * x) * c * x) * d) * h;
3390
+ case 29: return (h = (d = (c = x * x * x) * c * x) * d) * h * x;
3391
+ case 30: return (h = (d = (c = x * x * x) * c) * d * c) * h;
3392
+ case 31: return (h = (d = (c = x * x * x) * c) * d * c) * h * x;
3393
+ }
3394
+
3395
+ for ipow64: TODO
3396
+ switch (e) {
3397
+ case 32:
3398
+ ...
3399
+ case 63:
3400
+ }
3401
+ */