@amritk/nish-x86_64-linux 0.20.0 → 0.21.0
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.
- package/INSTALL.md +22 -10
- package/bin/nish +0 -0
- package/docs/AI.md +2759 -0
- package/package.json +2 -1
- package/runtime/browser.d.ts +14 -0
- package/runtime/browser.mjs +88 -0
- package/runtime/core/arrays.d.ts +18 -0
- package/runtime/core/arrays.mjs +125 -0
- package/runtime/core/checks.mjs +20 -0
- package/runtime/core/host.d.ts +70 -0
- package/runtime/core/host.mjs +311 -0
- package/runtime/core/numbers.d.ts +53 -0
- package/runtime/core/numbers.mjs +316 -0
- package/runtime/core/result.d.ts +41 -0
- package/runtime/core/result.mjs +127 -0
- package/runtime/core/strings.d.ts +14 -0
- package/runtime/core/strings.mjs +169 -0
- package/runtime/core.d.ts +9 -0
- package/runtime/core.mjs +55 -0
- package/runtime/host.d.ts +6 -0
- package/runtime/nish.d.ts +44 -0
- package/runtime/nish.h +75 -2
- package/runtime/nish.mjs +23 -3
- package/runtime/node.mjs +383 -0
- package/runtime/runtime-bytes.c +401 -0
- package/runtime/runtime-cross.c +1 -1
- package/runtime/runtime-host.c +1 -1
- package/runtime/runtime-os.c +1 -1
- package/runtime/runtime-parallel.c +1 -1
- package/runtime/runtime-simd.c +231 -7
- package/runtime/runtime-term.c +504 -0
- package/runtime/runtime-wasm.c +0 -11
- package/runtime/runtime.c +190 -6
- package/runtime/shim.mjs +6 -985
- package/runtime/sqlite/LICENSE.md +85 -0
- package/runtime/sqlite/README.md +45 -0
- package/runtime/sqlite/nish-sqlite.c +359 -0
- package/runtime/sqlite/sqlite3.c +271131 -0
- package/runtime/sqlite/sqlite3.h +14447 -0
- package/scripts/build.sh +261 -53
- package/std/LICENSE-fast-float +23 -0
- package/std/LICENSE-fdlibm +8 -0
- package/std/README.md +31 -11
- package/std/base64.ts +116 -0
- package/std/bytes.ts +256 -0
- package/std/cli.ts +328 -0
- package/std/collections.ts +6 -5
- package/std/crypto/LICENSE-crypt_blowfish +26 -0
- package/std/crypto/base64url.ts +125 -0
- package/std/crypto/bcrypt.ts +760 -0
- package/std/crypto/hmac.ts +138 -2
- package/std/crypto/x509.ts +11 -122
- package/std/json-tokenizer.ts +2998 -57
- package/std/json-value.ts +22 -3
- package/std/json.ts +83 -1
- package/std/math.ts +608 -0
- package/std/net/http1-server.ts +85 -8
- package/std/net/http3-server.ts +50 -12
- package/std/net/postgres.ts +1875 -0
- package/std/net/quic-listener.ts +20 -4
- package/std/regex.ts +4274 -0
- package/std/sqlite.ts +391 -0
- package/std/term-io.ts +978 -0
- package/std/term-pixels.ts +874 -0
- package/std/term-probe.ts +459 -0
- package/std/term-rate.ts +993 -0
- package/std/term.ts +2453 -0
- package/std/text.ts +90 -7
- package/std/yaml-lines.ts +141 -0
- package/std/yaml.ts +4675 -0
package/std/math.ts
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `std/math` — `Math.atan2`, `Math.tan` and `Math.hypot` on `f64`, in Nish
|
|
3
|
+
* rather than libm, so a program answers the same on every target, wasm
|
|
4
|
+
* included, and the optimiser sees the whole function.
|
|
5
|
+
*
|
|
6
|
+
* A program does not import this module. A call to one of the three is what
|
|
7
|
+
* loads it (the checker's `importMath`), and the compiler copies each function
|
|
8
|
+
* here that the call reaches into the calling module as an `internal`
|
|
9
|
+
* function, so this file writes no `.ll` of its own. Under Node and `tsc` the
|
|
10
|
+
* calls are the platform's `Math`, so nothing here runs there.
|
|
11
|
+
*
|
|
12
|
+
* **Exactness.** Each is within one ulp of the correctly rounded result, and
|
|
13
|
+
* exactly JavaScript's value for every NaN, signed zero and infinity — every
|
|
14
|
+
* `atan2` infinity pairing, and `hypot`'s Infinity when either operand is
|
|
15
|
+
* infinite, even beside a NaN. Measured against mpmath over 2.8
|
|
16
|
+
* million random and edge-case operands: `tan` 0.83 ulp, `atan2` 0.84 ulp,
|
|
17
|
+
* `hypot` 0.93 ulp (`tests/cases/math_std_edges` pins the special values).
|
|
18
|
+
*
|
|
19
|
+
* **`tan`** is fdlibm's `__kernel_tan` behind its Cody-Waite reduction for
|
|
20
|
+
* |x| below 2^20·π/2, with the quadrant's parity read from the rounding
|
|
21
|
+
* constant. Larger arguments reduce by an integer Payne-Hanek: 192 bits of
|
|
22
|
+
* 2/π against the 53-bit mantissa, which is exact near every multiple of π/2
|
|
23
|
+
* a double can name. **`atan2`** is fdlibm's, with the quotient `y/x`
|
|
24
|
+
* carried as a double-double, so the argument reduction loses nothing, and
|
|
25
|
+
* π − atan taken in double-double. **`hypot`** is fdlibm's core on operands
|
|
26
|
+
* in [1e-150, 1e150], where neither square can overflow, and a power-of-two
|
|
27
|
+
* rescale into that range otherwise.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
* Ported from fdlibm (https://www.netlib.org/fdlibm/), as FreeBSD msun carries
|
|
32
|
+
* it, lib/msun/src/k_tan.c, s_tan.c, e_rem_pio2.c, k_rem_pio2.c, e_atan2.c,
|
|
33
|
+
* s_atan.c and e_hypot.c. Copyright (C) 1993 by Sun Microsystems, Inc. Used under the
|
|
34
|
+
* fdlibm licence; see std/LICENSE-fdlibm.
|
|
35
|
+
*
|
|
36
|
+
* fdlibm's notice, as those files carry it:
|
|
37
|
+
*
|
|
38
|
+
* ====================================================
|
|
39
|
+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
40
|
+
*
|
|
41
|
+
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
|
42
|
+
* Permission to use, copy, modify, and distribute this
|
|
43
|
+
* software is freely granted, provided that this notice
|
|
44
|
+
* is preserved.
|
|
45
|
+
* ====================================================
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
// Word access, as fdlibm's GET_HIGH_WORD and GET_LOW_WORD.
|
|
49
|
+
const hiWord = (x: f64): i32 => toI32(f64ToBits(x) >> toI64(32))
|
|
50
|
+
const loWord = (x: f64): u32 => toU32(toU64(f64ToBits(x)))
|
|
51
|
+
const pow2 = (n: i32): f64 => bitsToF64(toI64(n + 1023) << toI64(52))
|
|
52
|
+
|
|
53
|
+
// biome-ignore lint/suspicious/noSelfCompare: NaN is the only value that is not itself; Nish has no Number.isNaN
|
|
54
|
+
const isNan = (v: f64): boolean => v !== v
|
|
55
|
+
|
|
56
|
+
const clearLo = (x: f64): f64 => bitsToF64(f64ToBits(x) & (toI64(-1) << toI64(32)))
|
|
57
|
+
|
|
58
|
+
// fdlibm's ipio2: 2/pi in 24-bit words, most significant first.
|
|
59
|
+
const ipio2 = (i: i32): i32 => {
|
|
60
|
+
switch (i) {
|
|
61
|
+
case 0:
|
|
62
|
+
return 0xa2f983
|
|
63
|
+
case 1:
|
|
64
|
+
return 0x6e4e44
|
|
65
|
+
case 2:
|
|
66
|
+
return 0x1529fc
|
|
67
|
+
case 3:
|
|
68
|
+
return 0x2757d1
|
|
69
|
+
case 4:
|
|
70
|
+
return 0xf534dd
|
|
71
|
+
case 5:
|
|
72
|
+
return 0xc0db62
|
|
73
|
+
case 6:
|
|
74
|
+
return 0x95993c
|
|
75
|
+
case 7:
|
|
76
|
+
return 0x439041
|
|
77
|
+
case 8:
|
|
78
|
+
return 0xfe5163
|
|
79
|
+
case 9:
|
|
80
|
+
return 0xabdebb
|
|
81
|
+
case 10:
|
|
82
|
+
return 0xc561b7
|
|
83
|
+
case 11:
|
|
84
|
+
return 0x246e3a
|
|
85
|
+
case 12:
|
|
86
|
+
return 0x424dd2
|
|
87
|
+
case 13:
|
|
88
|
+
return 0xe00649
|
|
89
|
+
case 14:
|
|
90
|
+
return 0x2eea09
|
|
91
|
+
case 15:
|
|
92
|
+
return 0xd1921c
|
|
93
|
+
case 16:
|
|
94
|
+
return 0xfe1deb
|
|
95
|
+
case 17:
|
|
96
|
+
return 0x1cb129
|
|
97
|
+
case 18:
|
|
98
|
+
return 0xa73ee8
|
|
99
|
+
case 19:
|
|
100
|
+
return 0x8235f5
|
|
101
|
+
case 20:
|
|
102
|
+
return 0x2ebb44
|
|
103
|
+
case 21:
|
|
104
|
+
return 0x84e99c
|
|
105
|
+
case 22:
|
|
106
|
+
return 0x7026b4
|
|
107
|
+
case 23:
|
|
108
|
+
return 0x5f7e41
|
|
109
|
+
case 24:
|
|
110
|
+
return 0x3991d6
|
|
111
|
+
case 25:
|
|
112
|
+
return 0x398353
|
|
113
|
+
case 26:
|
|
114
|
+
return 0x39f49c
|
|
115
|
+
case 27:
|
|
116
|
+
return 0x845f8b
|
|
117
|
+
case 28:
|
|
118
|
+
return 0xbdf928
|
|
119
|
+
case 29:
|
|
120
|
+
return 0x3b1ff8
|
|
121
|
+
case 30:
|
|
122
|
+
return 0x97ffde
|
|
123
|
+
case 31:
|
|
124
|
+
return 0x05980f
|
|
125
|
+
case 32:
|
|
126
|
+
return 0xef2f11
|
|
127
|
+
case 33:
|
|
128
|
+
return 0x8b5a0a
|
|
129
|
+
case 34:
|
|
130
|
+
return 0x6d1f6d
|
|
131
|
+
case 35:
|
|
132
|
+
return 0x367ecf
|
|
133
|
+
case 36:
|
|
134
|
+
return 0x27cb09
|
|
135
|
+
case 37:
|
|
136
|
+
return 0xb74f46
|
|
137
|
+
case 38:
|
|
138
|
+
return 0x3f669e
|
|
139
|
+
case 39:
|
|
140
|
+
return 0x5fea2d
|
|
141
|
+
case 40:
|
|
142
|
+
return 0x7527ba
|
|
143
|
+
case 41:
|
|
144
|
+
return 0xc7ebe5
|
|
145
|
+
case 42:
|
|
146
|
+
return 0xf17b3d
|
|
147
|
+
case 43:
|
|
148
|
+
return 0x0739f7
|
|
149
|
+
case 44:
|
|
150
|
+
return 0x8a5292
|
|
151
|
+
case 45:
|
|
152
|
+
return 0xea6bfb
|
|
153
|
+
case 46:
|
|
154
|
+
return 0x5fb11f
|
|
155
|
+
case 47:
|
|
156
|
+
return 0x8d5d08
|
|
157
|
+
case 48:
|
|
158
|
+
return 0x560330
|
|
159
|
+
case 49:
|
|
160
|
+
return 0x46fc7b
|
|
161
|
+
case 50:
|
|
162
|
+
return 0x6babf0
|
|
163
|
+
case 51:
|
|
164
|
+
return 0xcfbc20
|
|
165
|
+
case 52:
|
|
166
|
+
return 0x9af436
|
|
167
|
+
case 53:
|
|
168
|
+
return 0x1da9e3
|
|
169
|
+
case 54:
|
|
170
|
+
return 0x91615e
|
|
171
|
+
case 55:
|
|
172
|
+
return 0xe61b08
|
|
173
|
+
case 56:
|
|
174
|
+
return 0x659985
|
|
175
|
+
case 57:
|
|
176
|
+
return 0x5f14a0
|
|
177
|
+
case 58:
|
|
178
|
+
return 0x68408d
|
|
179
|
+
case 59:
|
|
180
|
+
return 0xffd880
|
|
181
|
+
case 60:
|
|
182
|
+
return 0x4d7327
|
|
183
|
+
case 61:
|
|
184
|
+
return 0x310606
|
|
185
|
+
case 62:
|
|
186
|
+
return 0x1556ca
|
|
187
|
+
case 63:
|
|
188
|
+
return 0x73a8c9
|
|
189
|
+
case 64:
|
|
190
|
+
return 0x60e27b
|
|
191
|
+
case 65:
|
|
192
|
+
return 0xc08c6b
|
|
193
|
+
default:
|
|
194
|
+
return 0
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Integer Payne-Hanek: 64 bits of 2/pi starting at fraction bit p (b_1 first).
|
|
199
|
+
const pio2Word = (p: i32): u64 => {
|
|
200
|
+
if (p < 1) {
|
|
201
|
+
return pio2Word(1) >> toU64(1 - p)
|
|
202
|
+
}
|
|
203
|
+
const j: i32 = (p - 1) / 24
|
|
204
|
+
const off: i32 = p - 1 - j * 24
|
|
205
|
+
const c0: u64 = toU64(ipio2(j))
|
|
206
|
+
const c1: u64 = toU64(ipio2(j + 1))
|
|
207
|
+
const c2: u64 = toU64(ipio2(j + 2))
|
|
208
|
+
const c3: u64 = toU64(ipio2(j + 3))
|
|
209
|
+
const top: u64 = (c0 << toU64(40)) | (c1 << toU64(16)) | (c2 >> toU64(8))
|
|
210
|
+
const low: u64 = ((c2 & toU64(255)) << toU64(24)) | c3
|
|
211
|
+
return (top << toU64(off)) | (low >> toU64(32 - off))
|
|
212
|
+
}
|
|
213
|
+
// The high 64 bits of a * b.
|
|
214
|
+
const mulHi = (a: u64, b: u64): u64 => {
|
|
215
|
+
const m32: u64 = (toU64(1) << toU64(32)) - toU64(1)
|
|
216
|
+
const a0: u64 = a & m32
|
|
217
|
+
const a1: u64 = a >> toU64(32)
|
|
218
|
+
const b0: u64 = b & m32
|
|
219
|
+
const b1: u64 = b >> toU64(32)
|
|
220
|
+
const p00: u64 = a0 * b0
|
|
221
|
+
const p01: u64 = a0 * b1
|
|
222
|
+
const p10: u64 = a1 * b0
|
|
223
|
+
const mid: u64 = (p00 >> toU64(32)) + (p01 & m32) + (p10 & m32)
|
|
224
|
+
return a1 * b1 + (p01 >> toU64(32)) + (p10 >> toU64(32)) + (mid >> toU64(32))
|
|
225
|
+
}
|
|
226
|
+
const clz64 = (v: u64): i32 => {
|
|
227
|
+
const h: u32 = toU32(v >> toU64(32))
|
|
228
|
+
return h !== toU32(0) ? Math.clz32(h) : Math.clz32(toU32(v)) + 32
|
|
229
|
+
}
|
|
230
|
+
// tan(x) for |x| >= 2^20 * pi/2 (finite): x * 2/pi mod 4 from a 192-bit window.
|
|
231
|
+
const tanLarge = (x: f64, ix: i32, hx: i32): f64 => {
|
|
232
|
+
const e: i32 = (ix >> 20) - 1023
|
|
233
|
+
const m: u64 = (toU64(f64ToBits(x)) & ((toU64(1) << toU64(52)) - toU64(1))) | (toU64(1) << toU64(52))
|
|
234
|
+
const p: i32 = e - 53
|
|
235
|
+
const w0: u64 = pio2Word(p)
|
|
236
|
+
const w1: u64 = pio2Word(p + 64)
|
|
237
|
+
const w2: u64 = pio2Word(p + 128)
|
|
238
|
+
const lo2: u64 = m * w2
|
|
239
|
+
const hi2: u64 = mulHi(m, w2)
|
|
240
|
+
const lo1: u64 = m * w1
|
|
241
|
+
const hi1: u64 = mulHi(m, w1)
|
|
242
|
+
const p0: u64 = lo2
|
|
243
|
+
const p1: u64 = hi2 + lo1
|
|
244
|
+
const c: u64 = p1 < lo1 ? toU64(1) : toU64(0)
|
|
245
|
+
const p2: u64 = hi1 + m * w0 + c
|
|
246
|
+
// Integer part mod 4 is the top two bits; the fraction is the rest, as a
|
|
247
|
+
// signed 192-bit number q2:q1:q0 in [-1/2, 1/2).
|
|
248
|
+
let n: i32 = toI32(p2 >> toU64(62))
|
|
249
|
+
let q2: u64 = (p2 << toU64(2)) | (p1 >> toU64(62))
|
|
250
|
+
let q1: u64 = (p1 << toU64(2)) | (p0 >> toU64(62))
|
|
251
|
+
let q0: u64 = p0 << toU64(2)
|
|
252
|
+
let neg: boolean = false
|
|
253
|
+
if (q2 >> toU64(63) !== toU64(0)) {
|
|
254
|
+
n += 1
|
|
255
|
+
neg = true
|
|
256
|
+
q0 = ~q0 + toU64(1)
|
|
257
|
+
const k0: u64 = q0 === toU64(0) ? toU64(1) : toU64(0)
|
|
258
|
+
q1 = ~q1 + k0
|
|
259
|
+
const k1: u64 = k0 !== toU64(0) && q1 === toU64(0) ? toU64(1) : toU64(0)
|
|
260
|
+
q2 = ~q2 + k1
|
|
261
|
+
}
|
|
262
|
+
let sh: i32 = 0
|
|
263
|
+
if (q2 === toU64(0)) {
|
|
264
|
+
q2 = q1
|
|
265
|
+
q1 = q0
|
|
266
|
+
q0 = toU64(0)
|
|
267
|
+
sh = 64
|
|
268
|
+
}
|
|
269
|
+
// lz is below 64: the fraction of an argument a double can name is never within 2^-128 of a
|
|
270
|
+
// multiple of pi/2, so after the one word shift above q2 is nonzero (a shift by 64 would be poison).
|
|
271
|
+
const lz: i32 = clz64(q2)
|
|
272
|
+
if (lz > 0) {
|
|
273
|
+
q2 = (q2 << toU64(lz)) | (q1 >> toU64(64 - lz))
|
|
274
|
+
q1 = (q1 << toU64(lz)) | (q0 >> toU64(64 - lz))
|
|
275
|
+
}
|
|
276
|
+
// f = (q2 * 2^-64 + q1 * 2^-128) * 2^-(sh + lz)
|
|
277
|
+
const a: f64 = toF64(q2 >> toU64(11)) * pow2(-53 - sh - lz)
|
|
278
|
+
const b: f64 = toF64(((q2 & toU64(2047)) << toU64(53)) | (q1 >> toU64(11))) * pow2(-117 - sh - lz)
|
|
279
|
+
// r = (a + b) * pi/2 as y0 + y1.
|
|
280
|
+
const p1h: f64 = 1.570796326794896558
|
|
281
|
+
const p1l: f64 = 6.12323399573676603587e-17
|
|
282
|
+
const t: f64 = a * p1h
|
|
283
|
+
const split: f64 = 134217729.0
|
|
284
|
+
const ac: f64 = a * split
|
|
285
|
+
const ah: f64 = ac - (ac - a)
|
|
286
|
+
const al: f64 = a - ah
|
|
287
|
+
const pc: f64 = p1h * split
|
|
288
|
+
const ph: f64 = pc - (pc - p1h)
|
|
289
|
+
const pl: f64 = p1h - ph
|
|
290
|
+
const err: f64 = ah * ph - t + ah * pl + al * ph + al * pl
|
|
291
|
+
const tail: f64 = err + (a * p1l + b * p1h)
|
|
292
|
+
let y0: f64 = t + tail
|
|
293
|
+
let y1: f64 = tail - (y0 - t)
|
|
294
|
+
if (neg !== hx < 0) {
|
|
295
|
+
y0 = -y0
|
|
296
|
+
y1 = -y1
|
|
297
|
+
}
|
|
298
|
+
return kernelTan(y0, y1, (n & 1) !== 0)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// fdlibm's __kernel_tan: tan(x0 + y0) for |x0 + y0| <= pi/4, or -1/tan when `odd`.
|
|
302
|
+
const kernelTan = (x0: f64, y0: f64, odd: boolean): f64 => {
|
|
303
|
+
let x: f64 = x0
|
|
304
|
+
let y: f64 = y0
|
|
305
|
+
const big: boolean = Math.abs(x) >= 0.6743354797363281
|
|
306
|
+
if (big) {
|
|
307
|
+
if (x0 < 0.0) {
|
|
308
|
+
x = -x
|
|
309
|
+
y = -y
|
|
310
|
+
}
|
|
311
|
+
x = 7.85398163397448278999e-1 - x + (3.06161699786838301793e-17 - y)
|
|
312
|
+
y = 0.0
|
|
313
|
+
}
|
|
314
|
+
const z: f64 = x * x
|
|
315
|
+
const w: f64 = z * z
|
|
316
|
+
const w2: f64 = w * w
|
|
317
|
+
const w4: f64 = w2 * w2
|
|
318
|
+
const r0: f64 =
|
|
319
|
+
2.18694882948595424599e-2 * w +
|
|
320
|
+
1.33333333333201242699e-1 +
|
|
321
|
+
w2 * (5.88041240820264096874e-4 * w + 3.59207910759131235356e-3) +
|
|
322
|
+
w4 * (-1.85586374855275456654e-5 * w + 7.817944429395570923e-5)
|
|
323
|
+
const v0: f64 =
|
|
324
|
+
z *
|
|
325
|
+
(8.86323982359930005737e-3 * w +
|
|
326
|
+
5.39682539762260521377e-2 +
|
|
327
|
+
w2 * (2.46463134818469906812e-4 * w + 1.45620945432529025516e-3) +
|
|
328
|
+
w4 * (2.59073051863633712884e-5 * w + 7.14072491382608190305e-5))
|
|
329
|
+
const s: f64 = z * x
|
|
330
|
+
let r: f64 = y + z * (s * (r0 + v0) + y)
|
|
331
|
+
r = r + 3.33333333333334091986e-1 * s
|
|
332
|
+
const wx: f64 = x + r
|
|
333
|
+
if (big) {
|
|
334
|
+
const v: f64 = odd ? -1.0 : 1.0
|
|
335
|
+
const res: f64 = v - (x - ((wx * wx) / (wx + v) - r)) * 2.0
|
|
336
|
+
return x0 < 0.0 ? -res : res
|
|
337
|
+
}
|
|
338
|
+
if (!odd) {
|
|
339
|
+
return wx
|
|
340
|
+
}
|
|
341
|
+
const zz: f64 = clearLo(wx)
|
|
342
|
+
const vv: f64 = r - (zz - x)
|
|
343
|
+
const a: f64 = -1.0 / wx
|
|
344
|
+
const t: f64 = clearLo(a)
|
|
345
|
+
return t + a * (t * zz + 1.0 + t * vv)
|
|
346
|
+
}
|
|
347
|
+
/** `Math.tan(x)`: fdlibm's reduction and kernel, with `tanLarge` past 2^20 * pi/2. */
|
|
348
|
+
export const tanF64 = (x: f64): f64 => {
|
|
349
|
+
const ax: f64 = Math.abs(x)
|
|
350
|
+
if (ax < 0.7853984832763672) {
|
|
351
|
+
if (ax < 7.450580596923828e-9) {
|
|
352
|
+
return x
|
|
353
|
+
}
|
|
354
|
+
return kernelTan(x, 0.0, false)
|
|
355
|
+
}
|
|
356
|
+
if (!(ax < 1647099.0)) {
|
|
357
|
+
if (isNan(ax) || ax > 1.7976931348623157e308) {
|
|
358
|
+
return x - x
|
|
359
|
+
}
|
|
360
|
+
const hx: i32 = hiWord(x)
|
|
361
|
+
return tanLarge(x, hx & 0x7fffffff, hx)
|
|
362
|
+
}
|
|
363
|
+
const rounded: f64 = x * 6.36619772367581382433e-1 + 6755399441055744.0
|
|
364
|
+
const fn: f64 = rounded - 6755399441055744.0
|
|
365
|
+
let r: f64 = x - fn * 1.57079632673412561417
|
|
366
|
+
let w: f64 = fn * 6.07710050650619224932e-11
|
|
367
|
+
let y0: f64 = r - w
|
|
368
|
+
// e_rem_pio2.c's refinement steps, taken when |y0| is below 2^-15 and 2^-48 of |x| rather than
|
|
369
|
+
// when the exponents differ by more than 16 and 49 as fdlibm tests them: a deliberate widening,
|
|
370
|
+
// since the compare can take a refinement fdlibm skips but never skip one fdlibm takes.
|
|
371
|
+
if (Math.abs(y0) < ax * 3.0517578125e-5) {
|
|
372
|
+
let t: f64 = r
|
|
373
|
+
w = fn * 6.0771005063039659766e-11
|
|
374
|
+
r = t - w
|
|
375
|
+
w = fn * 2.02226624879595063154e-21 - (t - r - w)
|
|
376
|
+
y0 = r - w
|
|
377
|
+
if (Math.abs(y0) < ax * 3.552713678800501e-15) {
|
|
378
|
+
t = r
|
|
379
|
+
w = fn * 2.0222662487111664558e-21
|
|
380
|
+
r = t - w
|
|
381
|
+
w = fn * 8.47842766036889956997e-32 - (t - r - w)
|
|
382
|
+
y0 = r - w
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const y1: f64 = r - y0 - w
|
|
386
|
+
return kernelTan(y0, y1, (f64ToBits(rounded) & toI64(1)) !== toI64(0))
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// fdlibm (FreeBSD msun) s_atan.c / e_atan2.c, ported.
|
|
390
|
+
const atanhi = (id: i32): f64 => {
|
|
391
|
+
switch (id) {
|
|
392
|
+
case 0:
|
|
393
|
+
return 4.63647609000806093515e-1
|
|
394
|
+
case 1:
|
|
395
|
+
return 7.85398163397448278999e-1
|
|
396
|
+
case 2:
|
|
397
|
+
return 9.82793723247329054082e-1
|
|
398
|
+
default:
|
|
399
|
+
return 1.570796326794896558
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const atanlo = (id: i32): f64 => {
|
|
403
|
+
switch (id) {
|
|
404
|
+
case 0:
|
|
405
|
+
return 2.26987774529616870924e-17
|
|
406
|
+
case 1:
|
|
407
|
+
return 3.06161699786838301793e-17
|
|
408
|
+
case 2:
|
|
409
|
+
return 1.39033110312309984516e-17
|
|
410
|
+
default:
|
|
411
|
+
return 6.12323399573676603587e-17
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/** `Math.atan2(y, x)`: fdlibm's, with a compensated quotient and a double-double pi - atan. */
|
|
416
|
+
export const atan2F64 = (y: f64, x: f64): f64 => {
|
|
417
|
+
const piO4: f64 = 7.85398163397448279e-1
|
|
418
|
+
const piO2: f64 = 1.570796326794896558
|
|
419
|
+
const pi: f64 = 3.141592653589793116
|
|
420
|
+
const piLo: f64 = 1.2246467991473531772e-16
|
|
421
|
+
if (isNan(x) || isNan(y)) {
|
|
422
|
+
return x + y
|
|
423
|
+
}
|
|
424
|
+
const hx: i32 = hiWord(x)
|
|
425
|
+
const lx: u32 = loWord(x)
|
|
426
|
+
const ix: i32 = hx & 0x7fffffff
|
|
427
|
+
const hy: i32 = hiWord(y)
|
|
428
|
+
const ly: u32 = loWord(y)
|
|
429
|
+
const iy: i32 = hy & 0x7fffffff
|
|
430
|
+
const m: i32 = ((hy >> 31) & 1) | ((hx >> 30) & 2)
|
|
431
|
+
if (iy === 0 && ly === 0) {
|
|
432
|
+
if (m < 2) {
|
|
433
|
+
return y
|
|
434
|
+
}
|
|
435
|
+
return m === 2 ? pi : -pi
|
|
436
|
+
}
|
|
437
|
+
if (ix === 0 && lx === 0) {
|
|
438
|
+
return hy < 0 ? -piO2 : piO2
|
|
439
|
+
}
|
|
440
|
+
if (ix === 0x7ff00000) {
|
|
441
|
+
if (iy === 0x7ff00000) {
|
|
442
|
+
switch (m) {
|
|
443
|
+
case 0:
|
|
444
|
+
return piO4
|
|
445
|
+
case 1:
|
|
446
|
+
return -piO4
|
|
447
|
+
case 2:
|
|
448
|
+
return 3.0 * piO4
|
|
449
|
+
default:
|
|
450
|
+
return -3.0 * piO4
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
switch (m) {
|
|
454
|
+
case 0:
|
|
455
|
+
return 0.0
|
|
456
|
+
case 1:
|
|
457
|
+
return -0.0
|
|
458
|
+
case 2:
|
|
459
|
+
return pi
|
|
460
|
+
default:
|
|
461
|
+
return -pi
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (iy === 0x7ff00000) {
|
|
465
|
+
return hy < 0 ? -piO2 : piO2
|
|
466
|
+
}
|
|
467
|
+
const k: i32 = (iy - ix) >> 20
|
|
468
|
+
if (k > 60) {
|
|
469
|
+
const r: f64 = piO2 + 0.5 * piLo
|
|
470
|
+
return hy < 0 ? -r : r
|
|
471
|
+
}
|
|
472
|
+
if (k < -60) {
|
|
473
|
+
if (hx < 0) {
|
|
474
|
+
return hy < 0 ? -pi : pi
|
|
475
|
+
}
|
|
476
|
+
const q: f64 = y / x
|
|
477
|
+
return q
|
|
478
|
+
}
|
|
479
|
+
let a: f64 = Math.abs(y)
|
|
480
|
+
let b: f64 = Math.abs(x)
|
|
481
|
+
if (ix < 0x23d00000 || ix > 0x5c100000) {
|
|
482
|
+
const h: i32 = -((ix >> 20) - 1023)
|
|
483
|
+
const h1: i32 = h >> 1
|
|
484
|
+
const s: f64 = pow2(h1) * pow2(h - h1)
|
|
485
|
+
a = a * s
|
|
486
|
+
b = b * s
|
|
487
|
+
}
|
|
488
|
+
const q: f64 = a / b
|
|
489
|
+
const qs: f64 = q * 134217729.0
|
|
490
|
+
const qh: f64 = qs - (qs - q)
|
|
491
|
+
const ql: f64 = q - qh
|
|
492
|
+
const bs: f64 = b * 134217729.0
|
|
493
|
+
const bh: f64 = bs - (bs - b)
|
|
494
|
+
const bl: f64 = b - bh
|
|
495
|
+
const p: f64 = q * b
|
|
496
|
+
const pe: f64 = qh * bh - p + qh * bl + ql * bh + ql * bl
|
|
497
|
+
const c: f64 = (a - p - pe) / (b + a * q)
|
|
498
|
+
let hi: f64 = 0.0
|
|
499
|
+
let lo: f64 = 0.0
|
|
500
|
+
const iq: i32 = hiWord(q)
|
|
501
|
+
if (iq >= 0x44100000) {
|
|
502
|
+
hi = atanhi(3)
|
|
503
|
+
lo = atanlo(3)
|
|
504
|
+
} else if (iq < 0x3e400000) {
|
|
505
|
+
lo = q
|
|
506
|
+
} else {
|
|
507
|
+
let t: f64 = q
|
|
508
|
+
let tl: f64 = c
|
|
509
|
+
if (iq >= 0x3fdc0000) {
|
|
510
|
+
let id: i32 = 3
|
|
511
|
+
if (iq < 0x3ff30000) {
|
|
512
|
+
if (iq < 0x3fe60000) {
|
|
513
|
+
id = 0
|
|
514
|
+
t = (2.0 * q - 1.0) / (q + 2.0)
|
|
515
|
+
} else {
|
|
516
|
+
id = 1
|
|
517
|
+
t = (q - 1.0) / (q + 1.0)
|
|
518
|
+
}
|
|
519
|
+
} else if (iq < 0x40038000) {
|
|
520
|
+
id = 2
|
|
521
|
+
t = (q - 1.5) / (q * 1.5 + 1.0)
|
|
522
|
+
} else {
|
|
523
|
+
t = -1.0 / q
|
|
524
|
+
}
|
|
525
|
+
hi = atanhi(id)
|
|
526
|
+
tl = atanlo(id) + c
|
|
527
|
+
}
|
|
528
|
+
const z: f64 = t * t
|
|
529
|
+
const w: f64 = z * z
|
|
530
|
+
const s1: f64 =
|
|
531
|
+
z *
|
|
532
|
+
(((((1.62858201153657823623e-2 * w + 4.97687799461593236017e-2) * w + 6.66107313738753120669e-2) * w +
|
|
533
|
+
9.09088713343650656196e-2) *
|
|
534
|
+
w +
|
|
535
|
+
1.42857142725034663711e-1) *
|
|
536
|
+
w +
|
|
537
|
+
3.33333333333329318027e-1)
|
|
538
|
+
const s2: f64 =
|
|
539
|
+
w *
|
|
540
|
+
((((-3.6531572744216915527e-2 * w - 5.83357013379057348645e-2) * w - 7.69187620504482999495e-2) * w -
|
|
541
|
+
1.1111110405462355788e-1) *
|
|
542
|
+
w -
|
|
543
|
+
1.99999999998764832476e-1)
|
|
544
|
+
lo = t - (t * (s1 + s2) - tl)
|
|
545
|
+
}
|
|
546
|
+
let r: f64 = 0.0
|
|
547
|
+
if (hx >= 0) {
|
|
548
|
+
r = hi + lo
|
|
549
|
+
} else {
|
|
550
|
+
const s: f64 = pi - hi
|
|
551
|
+
r = s + (piLo - lo + (pi - s - hi))
|
|
552
|
+
}
|
|
553
|
+
return hy < 0 ? -r : r
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// The fdlibm core for a in [1e-150, 1e150] and b <= a: neither square overflows, and a b small
|
|
557
|
+
// enough for its square to underflow is below a * 2^-54, where it cannot move the answer.
|
|
558
|
+
const hypotCoreF = (a: f64, b: f64): f64 => {
|
|
559
|
+
const w: f64 = a - b
|
|
560
|
+
if (w > b) {
|
|
561
|
+
const t1: f64 = clearLo(a)
|
|
562
|
+
const t2: f64 = a - t1
|
|
563
|
+
return Math.sqrt(t1 * t1 - (b * -b - t2 * (a + t1)))
|
|
564
|
+
}
|
|
565
|
+
const a2: f64 = a + a
|
|
566
|
+
const y1: f64 = clearLo(b)
|
|
567
|
+
const y2: f64 = b - y1
|
|
568
|
+
const t1: f64 = clearLo(a2)
|
|
569
|
+
const t2: f64 = a2 - t1
|
|
570
|
+
return Math.sqrt(t1 * y1 - (w * -w - (t1 * y2 + t2 * b)))
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Every case outside the core: an infinity wins over a NaN, a zero b gives a, and otherwise both
|
|
574
|
+
// operands are scaled by a power of two into the core's range and the answer back out of it.
|
|
575
|
+
const hypotRest = (ax: f64, ay: f64, a: f64, b: f64): f64 => {
|
|
576
|
+
const one: f64 = 1.0
|
|
577
|
+
const inf: f64 = one / 0.0
|
|
578
|
+
if (ax === inf || ay === inf) {
|
|
579
|
+
return inf
|
|
580
|
+
}
|
|
581
|
+
if (isNan(a) || isNan(b)) {
|
|
582
|
+
return ax + ay
|
|
583
|
+
}
|
|
584
|
+
if (b === 0.0) {
|
|
585
|
+
return a
|
|
586
|
+
}
|
|
587
|
+
if (a > 1.0) {
|
|
588
|
+
const down: f64 = pow2(-600)
|
|
589
|
+
return pow2(600) * hypotCoreF(a * down, b * down)
|
|
590
|
+
}
|
|
591
|
+
const up: f64 = pow2(600)
|
|
592
|
+
return pow2(-600) * hypotCoreF(a * up, b * up)
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/** `Math.hypot(x, y)`: fdlibm's core, rescaled by a power of two outside [1e-150, 1e150]. */
|
|
596
|
+
export const hypotF64 = (x: f64, y: f64): f64 => {
|
|
597
|
+
const ax: f64 = Math.abs(x)
|
|
598
|
+
const ay: f64 = Math.abs(y)
|
|
599
|
+
const a: f64 = ax > ay ? ax : ay
|
|
600
|
+
const b: f64 = ax > ay ? ay : ax
|
|
601
|
+
if (a < 1.0e150 && a > 1.0e-150) {
|
|
602
|
+
// JavaScript's `hypot(x, 0)` is `|x|` exactly. The core gives it too -- its sum is a^2 to
|
|
603
|
+
// within 2^-18 ulp before rounding, and the root of a double that near a^2 rounds to a -- so
|
|
604
|
+
// the compare only skips the core's work.
|
|
605
|
+
return b === 0.0 ? a : hypotCoreF(a, b)
|
|
606
|
+
}
|
|
607
|
+
return hypotRest(ax, ay, a, b)
|
|
608
|
+
}
|