json-as 1.3.0 → 1.3.2
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/CHANGELOG.md +400 -0
- package/README.md +137 -32
- package/assembly/deserialize/index/arbitrary.ts +1 -1
- package/assembly/deserialize/index/array.ts +6 -1
- package/assembly/deserialize/index/float.ts +1 -1
- package/assembly/deserialize/index/integer.ts +1 -1
- package/assembly/deserialize/index/typedarray.ts +14 -0
- package/assembly/deserialize/index/unsigned.ts +1 -1
- package/assembly/deserialize/simd/string.ts +20 -16
- package/assembly/deserialize/simple/arbitrary.ts +1 -1
- package/assembly/deserialize/simple/array/generic.ts +42 -0
- package/assembly/deserialize/simple/array.ts +8 -1
- package/assembly/deserialize/{float.ts → simple/float.ts} +22 -2
- package/assembly/deserialize/{integer.ts → simple/integer.ts} +3 -2
- package/assembly/deserialize/simple/map.ts +60 -12
- package/assembly/deserialize/simple/object.ts +1 -1
- package/assembly/deserialize/simple/set.ts +119 -134
- package/assembly/deserialize/simple/staticarray.ts +12 -1
- package/assembly/deserialize/simple/string.ts +93 -2
- package/assembly/deserialize/simple/struct.ts +7 -157
- package/assembly/deserialize/simple/typedarray.ts +1 -1
- package/assembly/deserialize/{unsigned.ts → simple/unsigned.ts} +3 -2
- package/assembly/deserialize/swar/array/array.ts +42 -7
- package/assembly/deserialize/swar/array/bool.ts +5 -2
- package/assembly/deserialize/swar/array/float.ts +7 -3
- package/assembly/deserialize/swar/array/generic.ts +40 -0
- package/assembly/deserialize/swar/array/integer.ts +7 -4
- package/assembly/deserialize/swar/array/object.ts +20 -4
- package/assembly/deserialize/swar/array/shared.ts +18 -4
- package/assembly/deserialize/swar/array/string.ts +5 -2
- package/assembly/deserialize/swar/array/struct.ts +20 -4
- package/assembly/deserialize/swar/array.ts +56 -2
- package/assembly/deserialize/swar/string.ts +245 -370
- package/assembly/index.ts +207 -194
- package/assembly/serialize/index/arbitrary.ts +8 -3
- package/assembly/serialize/index/float.ts +1 -1
- package/assembly/serialize/index/object.ts +1 -5
- package/assembly/serialize/index/typedarray.ts +65 -0
- package/assembly/serialize/simd/string.ts +7 -16
- package/assembly/serialize/simple/arbitrary.ts +9 -3
- package/assembly/serialize/simple/array.ts +17 -6
- package/assembly/serialize/simple/float.ts +18 -4
- package/assembly/serialize/simple/map.ts +10 -27
- package/assembly/serialize/simple/object.ts +1 -5
- package/assembly/serialize/simple/set.ts +3 -4
- package/assembly/serialize/simple/staticarray.ts +4 -3
- package/assembly/serialize/simple/string.ts +3 -11
- package/assembly/serialize/simple/typedarray.ts +9 -7
- package/assembly/serialize/swar/string.ts +3 -12
- package/assembly/tsconfig.json +3 -2
- package/assembly/util/dragonbox-cache.ts +1322 -0
- package/assembly/util/dragonbox.ts +596 -0
- package/assembly/util/swar.ts +49 -0
- package/lib/as-bs.ts +92 -70
- package/package.json +35 -10
- package/transform/lib/index.d.ts +1 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +559 -221
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linkers/custom.d.ts.map +1 -1
- package/transform/lib/linkers/custom.js +7 -3
- package/transform/lib/linkers/custom.js.map +1 -1
- package/transform/lib/types.d.ts +2 -0
- package/transform/lib/types.d.ts.map +1 -1
- package/transform/lib/types.js +13 -0
- package/transform/lib/types.js.map +1 -1
- package/.as-test/coverage/naive/coverage.arbitrary.spec.ts.log.json +0 -5628
- package/.as-test/coverage/naive/coverage.array.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.bool.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.box.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.custom.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.date.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.enum.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.float.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.generics.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.hierarchy.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.integer.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.map.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.namespace.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.null.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.raw.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.resolving.spec.ts.log.json +0 -5628
- package/.as-test/coverage/naive/coverage.set.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.staticarray.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.string.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.struct.spec.ts.log.json +0 -5187
- package/.as-test/coverage/naive/coverage.types.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.arbitrary.spec.ts.log.json +0 -5628
- package/.as-test/coverage/simd/coverage.array.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.bool.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.box.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.custom.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.date.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.enum.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.float.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.generics.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.hierarchy.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.integer.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.map.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.namespace.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.null.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.raw.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.resolving.spec.ts.log.json +0 -5628
- package/.as-test/coverage/simd/coverage.set.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.staticarray.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.string.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.struct.spec.ts.log.json +0 -5187
- package/.as-test/coverage/simd/coverage.types.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.arbitrary.spec.ts.log.json +0 -5628
- package/.as-test/coverage/swar/coverage.array.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.bool.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.box.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.custom.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.date.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.enum.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.float.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.generics.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.hierarchy.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.integer.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.map.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.namespace.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.null.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.raw.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.resolving.spec.ts.log.json +0 -5628
- package/.as-test/coverage/swar/coverage.set.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.staticarray.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.string.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.struct.spec.ts.log.json +0 -5187
- package/.as-test/coverage/swar/coverage.types.spec.ts.log.json +0 -5187
- package/.as-test/logs/naive/run.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/naive/run.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/naive/run.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/naive/run.box.spec.ts.log.json +0 -353
- package/.as-test/logs/naive/run.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/naive/run.date.spec.ts.log.json +0 -397
- package/.as-test/logs/naive/run.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/naive/run.float.spec.ts.log.json +0 -453
- package/.as-test/logs/naive/run.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/naive/run.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/naive/run.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/naive/run.map.spec.ts.log.json +0 -247
- package/.as-test/logs/naive/run.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/naive/run.null.spec.ts.log.json +0 -273
- package/.as-test/logs/naive/run.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/naive/run.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/naive/run.set.spec.ts.log.json +0 -733
- package/.as-test/logs/naive/run.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/naive/run.string.spec.ts.log.json +0 -2289
- package/.as-test/logs/naive/run.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/naive/run.types.spec.ts.log.json +0 -273
- package/.as-test/logs/naive/test.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/naive/test.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/naive/test.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/naive/test.box.spec.ts.log.json +0 -353
- package/.as-test/logs/naive/test.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/naive/test.date.spec.ts.log.json +0 -397
- package/.as-test/logs/naive/test.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/naive/test.float.spec.ts.log.json +0 -453
- package/.as-test/logs/naive/test.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/naive/test.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/naive/test.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/naive/test.log.json +0 -2289
- package/.as-test/logs/naive/test.map.spec.ts.log.json +0 -247
- package/.as-test/logs/naive/test.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/naive/test.null.spec.ts.log.json +0 -273
- package/.as-test/logs/naive/test.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/naive/test.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/naive/test.set.spec.ts.log.json +0 -733
- package/.as-test/logs/naive/test.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/naive/test.string.spec.ts.log.json +0 -2345
- package/.as-test/logs/naive/test.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/naive/test.types.spec.ts.log.json +0 -273
- package/.as-test/logs/simd/run.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/simd/run.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/simd/run.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/simd/run.box.spec.ts.log.json +0 -353
- package/.as-test/logs/simd/run.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/simd/run.date.spec.ts.log.json +0 -397
- package/.as-test/logs/simd/run.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/simd/run.float.spec.ts.log.json +0 -453
- package/.as-test/logs/simd/run.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/simd/run.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/simd/run.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/simd/run.map.spec.ts.log.json +0 -247
- package/.as-test/logs/simd/run.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/simd/run.null.spec.ts.log.json +0 -273
- package/.as-test/logs/simd/run.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/simd/run.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/simd/run.set.spec.ts.log.json +0 -733
- package/.as-test/logs/simd/run.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/simd/run.string.spec.ts.log.json +0 -2289
- package/.as-test/logs/simd/run.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/simd/run.types.spec.ts.log.json +0 -273
- package/.as-test/logs/simd/test.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/simd/test.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/simd/test.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/simd/test.box.spec.ts.log.json +0 -353
- package/.as-test/logs/simd/test.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/simd/test.date.spec.ts.log.json +0 -397
- package/.as-test/logs/simd/test.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/simd/test.float.spec.ts.log.json +0 -453
- package/.as-test/logs/simd/test.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/simd/test.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/simd/test.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/simd/test.log.json +0 -11371
- package/.as-test/logs/simd/test.map.spec.ts.log.json +0 -247
- package/.as-test/logs/simd/test.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/simd/test.null.spec.ts.log.json +0 -273
- package/.as-test/logs/simd/test.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/simd/test.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/simd/test.set.spec.ts.log.json +0 -733
- package/.as-test/logs/simd/test.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/simd/test.string.spec.ts.log.json +0 -2345
- package/.as-test/logs/simd/test.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/simd/test.types.spec.ts.log.json +0 -273
- package/.as-test/logs/swar/run.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/swar/run.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/swar/run.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/swar/run.box.spec.ts.log.json +0 -353
- package/.as-test/logs/swar/run.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/swar/run.date.spec.ts.log.json +0 -397
- package/.as-test/logs/swar/run.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/swar/run.float.spec.ts.log.json +0 -453
- package/.as-test/logs/swar/run.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/swar/run.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/swar/run.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/swar/run.map.spec.ts.log.json +0 -247
- package/.as-test/logs/swar/run.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/swar/run.null.spec.ts.log.json +0 -273
- package/.as-test/logs/swar/run.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/swar/run.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/swar/run.set.spec.ts.log.json +0 -733
- package/.as-test/logs/swar/run.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/swar/run.string.spec.ts.log.json +0 -2289
- package/.as-test/logs/swar/run.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/swar/run.types.spec.ts.log.json +0 -273
- package/.as-test/logs/swar/test.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/swar/test.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/swar/test.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/swar/test.box.spec.ts.log.json +0 -353
- package/.as-test/logs/swar/test.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/swar/test.date.spec.ts.log.json +0 -397
- package/.as-test/logs/swar/test.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/swar/test.float.spec.ts.log.json +0 -453
- package/.as-test/logs/swar/test.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/swar/test.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/swar/test.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/swar/test.log.json +0 -11371
- package/.as-test/logs/swar/test.map.spec.ts.log.json +0 -247
- package/.as-test/logs/swar/test.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/swar/test.null.spec.ts.log.json +0 -273
- package/.as-test/logs/swar/test.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/swar/test.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/swar/test.set.spec.ts.log.json +0 -733
- package/.as-test/logs/swar/test.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/swar/test.string.spec.ts.log.json +0 -2345
- package/.as-test/logs/swar/test.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/swar/test.types.spec.ts.log.json +0 -273
- package/.as-test/logs/test.arbitrary.spec.ts.log.json +0 -943
- package/.as-test/logs/test.array.spec.ts.log.json +0 -1053
- package/.as-test/logs/test.bool.spec.ts.log.json +0 -257
- package/.as-test/logs/test.box.spec.ts.log.json +0 -353
- package/.as-test/logs/test.custom.spec.ts.log.json +0 -309
- package/.as-test/logs/test.date.spec.ts.log.json +0 -397
- package/.as-test/logs/test.enum.spec.ts.log.json +0 -343
- package/.as-test/logs/test.float.spec.ts.log.json +0 -453
- package/.as-test/logs/test.generics.spec.ts.log.json +0 -393
- package/.as-test/logs/test.hierarchy.spec.ts.log.json +0 -325
- package/.as-test/logs/test.integer.spec.ts.log.json +0 -373
- package/.as-test/logs/test.log.json +0 -11371
- package/.as-test/logs/test.map.spec.ts.log.json +0 -247
- package/.as-test/logs/test.namespace.spec.ts.log.json +0 -361
- package/.as-test/logs/test.null.spec.ts.log.json +0 -273
- package/.as-test/logs/test.raw.spec.ts.log.json +0 -309
- package/.as-test/logs/test.resolving.spec.ts.log.json +0 -273
- package/.as-test/logs/test.set.spec.ts.log.json +0 -733
- package/.as-test/logs/test.staticarray.spec.ts.log.json +0 -931
- package/.as-test/logs/test.string.spec.ts.log.json +0 -2289
- package/.as-test/logs/test.struct.spec.ts.log.json +0 -523
- package/.as-test/logs/test.types.spec.ts.log.json +0 -273
- package/.as-test/runners/default.bindings.js +0 -68
- package/.as-test/runners/default.wasi.js +0 -38
- package/ARCHITECTURE.md +0 -323
- package/CONTRIBUTING.md +0 -244
- package/TODO +0 -1
- package/as-test.config.json +0 -40
- package/assembly/test.ts +0 -24
- package/eslint.config.js +0 -68
- package/lib/tsconfig.json +0 -8
- package/test.ts +0 -99
- package/tools/assemblyscript-eslint-local.js +0 -6
- package/tools/assemblyscript-eslint.js +0 -53
- package/tools/assemblyscript-prettier-plugin.js +0 -33
- package/tools/replacer.js +0 -63
- package/transform/tsconfig.json +0 -35
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
import { DRAGONBOX_F32_CACHE, DRAGONBOX_F64_CACHE } from "./dragonbox-cache";
|
|
2
|
+
import { decimalCount32, itoa_buffered, utoa32_dec_core } from "util/number";
|
|
3
|
+
|
|
4
|
+
const CHAR_MINUS: u16 = 45;
|
|
5
|
+
const CHAR_DOT: u16 = 46;
|
|
6
|
+
const CHAR_0: u16 = 48;
|
|
7
|
+
const CHAR_E: u16 = 101;
|
|
8
|
+
const CHAR_PLUS: u16 = 43;
|
|
9
|
+
|
|
10
|
+
let _dbK: i32 = 0;
|
|
11
|
+
let _dbMulInteger32: u32 = 0;
|
|
12
|
+
let _dbMulInteger64: u64 = 0;
|
|
13
|
+
let _dbMulIsInteger: bool = false;
|
|
14
|
+
let _dbParity: bool = false;
|
|
15
|
+
let _dbRemovedExponent: i32 = 0;
|
|
16
|
+
|
|
17
|
+
@inline
|
|
18
|
+
function rotr32(n: u32, r: i32): u32 {
|
|
19
|
+
const s = r & 31;
|
|
20
|
+
return (n >>> s) | (n << ((32 - s) & 31));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@inline
|
|
24
|
+
function rotr64(n: u64, r: i32): u64 {
|
|
25
|
+
const s = r & 63;
|
|
26
|
+
return (n >>> s) | (n << ((64 - s) & 63));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@inline
|
|
30
|
+
function floor_log10_pow2(e: i32): i32 {
|
|
31
|
+
return (e * 315653) >> 20;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@inline
|
|
35
|
+
function floor_log2_pow10(e: i32): i32 {
|
|
36
|
+
return (e * 1741647) >> 19;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@inline
|
|
40
|
+
function floor_log10_pow2_minus_log10_4_over_3(e: i32): i32 {
|
|
41
|
+
return (e * 631305 - 261663) >> 21;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@inline
|
|
45
|
+
function floor_log5_pow2(e: i32): i32 {
|
|
46
|
+
return (e * 225799) >> 19;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@inline
|
|
50
|
+
function floor_log5_pow2_minus_log5_3(e: i32): i32 {
|
|
51
|
+
return (e * 451597 - 715764) >> 20;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@inline
|
|
55
|
+
function umul128_upper64(x: u64, y: u64): u64 {
|
|
56
|
+
const a = <u32>(x >>> 32);
|
|
57
|
+
const b = <u32>x;
|
|
58
|
+
const c = <u32>(y >>> 32);
|
|
59
|
+
const d = <u32>y;
|
|
60
|
+
const ac = <u64>a * c;
|
|
61
|
+
const bc = <u64>b * c;
|
|
62
|
+
const ad = <u64>a * d;
|
|
63
|
+
const bd = <u64>b * d;
|
|
64
|
+
const intermediate = (bd >>> 32) + <u32>ad + <u32>bc;
|
|
65
|
+
return ac + (intermediate >>> 32) + (ad >>> 32) + (bc >>> 32);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@inline
|
|
69
|
+
function umul96_upper64(x: u32, y: u64): u64 {
|
|
70
|
+
const yh = <u32>(y >>> 32);
|
|
71
|
+
const yl = <u32>y;
|
|
72
|
+
const xyh = <u64>x * yh;
|
|
73
|
+
const xyl = <u64>x * yl;
|
|
74
|
+
return xyh + (xyl >>> 32);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@inline
|
|
78
|
+
function computeMul32(u: u32, cache: u64): void {
|
|
79
|
+
const r = umul96_upper64(u, cache);
|
|
80
|
+
_dbMulInteger32 = <u32>(r >>> 32);
|
|
81
|
+
_dbMulIsInteger = <u32>r == 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@inline
|
|
85
|
+
function computeMulParity32(twoF: u32, cache: u64, beta: i32): void {
|
|
86
|
+
const r = <u64>twoF * cache;
|
|
87
|
+
_dbParity = ((r >>> (64 - beta)) & 1) != 0;
|
|
88
|
+
_dbMulIsInteger = (<u32>(r >>> (32 - beta))) == 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@inline
|
|
92
|
+
function computeLeftEndpointShorter32(cache: u64, beta: i32): u32 {
|
|
93
|
+
return <u32>((cache - (cache >>> 25)) >>> (40 - beta));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@inline
|
|
97
|
+
function computeRightEndpointShorter32(cache: u64, beta: i32): u32 {
|
|
98
|
+
return <u32>((cache + (cache >>> 24)) >>> (40 - beta));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@inline
|
|
102
|
+
function computeRoundUpShorter32(cache: u64, beta: i32): u32 {
|
|
103
|
+
return (<u32>(cache >>> (39 - beta)) + 1) >>> 1;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@inline
|
|
107
|
+
function removeTrailingZeros32(significand: u32): u32 {
|
|
108
|
+
let exponent = 0;
|
|
109
|
+
let r = rotr32(significand * 184254097, 4);
|
|
110
|
+
let b = r < 429497;
|
|
111
|
+
let s: u32 = b ? 1 : 0;
|
|
112
|
+
if (b) significand = r;
|
|
113
|
+
|
|
114
|
+
r = rotr32(significand * 42949673, 2);
|
|
115
|
+
b = r < 42949673;
|
|
116
|
+
s = s * 2 + (b ? 1 : 0);
|
|
117
|
+
if (b) significand = r;
|
|
118
|
+
|
|
119
|
+
r = rotr32(significand * 1288490189, 1);
|
|
120
|
+
b = r < 429496730;
|
|
121
|
+
s = s * 2 + (b ? 1 : 0);
|
|
122
|
+
if (b) significand = r;
|
|
123
|
+
|
|
124
|
+
exponent += s;
|
|
125
|
+
_dbRemovedExponent = exponent;
|
|
126
|
+
return significand;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@inline
|
|
130
|
+
function divideByPow10_32_1(n: u32): u32 {
|
|
131
|
+
return <u32>((<u64>n * 429496730) >>> 32);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@inline
|
|
135
|
+
function divideByPow10_32_2(n: u32): u32 {
|
|
136
|
+
return <u32>((<u64>n * 1374389535) >>> 37);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@inline
|
|
140
|
+
function checkDivisibilityAndDivideByPow10_32_1(n: u32): u64 {
|
|
141
|
+
const prod = <u32>(n * 6554);
|
|
142
|
+
return (<u64>(prod >>> 16) << 32) | (((prod & 0xFFFF) < 6554) ? 1 : 0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@inline
|
|
146
|
+
function computeMul64(u: u64, cacheHigh: u64, cacheLow: u64): void {
|
|
147
|
+
const high = umul128_upper64(u, cacheHigh);
|
|
148
|
+
|
|
149
|
+
const a = <u32>(u >>> 32);
|
|
150
|
+
const b = <u32>u;
|
|
151
|
+
const c = <u32>(cacheHigh >>> 32);
|
|
152
|
+
const d = <u32>cacheHigh;
|
|
153
|
+
const ac = <u64>a * c;
|
|
154
|
+
const bc = <u64>b * c;
|
|
155
|
+
const ad = <u64>a * d;
|
|
156
|
+
const bd = <u64>b * d;
|
|
157
|
+
let intermediate = (bd >>> 32) + <u32>ad + <u32>bc;
|
|
158
|
+
let rHigh = ac + (intermediate >>> 32) + (ad >>> 32) + (bc >>> 32);
|
|
159
|
+
let rLow = (intermediate << 32) + <u32>bd;
|
|
160
|
+
|
|
161
|
+
const add = umul128_upper64(u, cacheLow);
|
|
162
|
+
const sumLow = rLow + add;
|
|
163
|
+
rHigh += sumLow < rLow ? 1 : 0;
|
|
164
|
+
rLow = sumLow;
|
|
165
|
+
|
|
166
|
+
_dbMulInteger64 = rHigh;
|
|
167
|
+
_dbMulIsInteger = rLow == 0;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@inline
|
|
171
|
+
function computeMulParity64(twoF: u64, cacheHigh: u64, cacheLow: u64, beta: i32): void {
|
|
172
|
+
const high = twoF * cacheHigh;
|
|
173
|
+
|
|
174
|
+
const a = <u32>(twoF >>> 32);
|
|
175
|
+
const b = <u32>twoF;
|
|
176
|
+
const c = <u32>(cacheLow >>> 32);
|
|
177
|
+
const d = <u32>cacheLow;
|
|
178
|
+
const ac = <u64>a * c;
|
|
179
|
+
const bc = <u64>b * c;
|
|
180
|
+
const ad = <u64>a * d;
|
|
181
|
+
const bd = <u64>b * d;
|
|
182
|
+
const intermediate = (bd >>> 32) + <u32>ad + <u32>bc;
|
|
183
|
+
const lowHigh = ac + (intermediate >>> 32) + (ad >>> 32) + (bc >>> 32);
|
|
184
|
+
const lowLow = (intermediate << 32) + <u32>bd;
|
|
185
|
+
|
|
186
|
+
const rHigh = high + lowHigh;
|
|
187
|
+
_dbParity = ((rHigh >>> (64 - beta)) & 1) != 0;
|
|
188
|
+
_dbMulIsInteger = ((((rHigh << beta) & 0xFFFFFFFFFFFFFFFF) | (lowLow >>> (64 - beta))) == 0);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@inline
|
|
192
|
+
function computeLeftEndpointShorter64(cacheHigh: u64, beta: i32): u64 {
|
|
193
|
+
return (cacheHigh - (cacheHigh >>> 54)) >>> (11 - beta);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@inline
|
|
197
|
+
function computeRightEndpointShorter64(cacheHigh: u64, beta: i32): u64 {
|
|
198
|
+
return (cacheHigh + (cacheHigh >>> 53)) >>> (11 - beta);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@inline
|
|
202
|
+
function computeRoundUpShorter64(cacheHigh: u64, beta: i32): u64 {
|
|
203
|
+
return ((cacheHigh >>> (10 - beta)) + 1) >>> 1;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@inline
|
|
207
|
+
function removeTrailingZeros64(significand: u64): u64 {
|
|
208
|
+
let exponent = 0;
|
|
209
|
+
let r = rotr64(significand * 28999941890838049, 8);
|
|
210
|
+
let b = r < 184467440738;
|
|
211
|
+
let s: u32 = b ? 1 : 0;
|
|
212
|
+
if (b) significand = r;
|
|
213
|
+
|
|
214
|
+
r = rotr64(significand * 182622766329724561, 4);
|
|
215
|
+
b = r < 1844674407370956;
|
|
216
|
+
s = s * 2 + (b ? 1 : 0);
|
|
217
|
+
if (b) significand = r;
|
|
218
|
+
|
|
219
|
+
r = rotr64(significand * 10330176681277348905, 2);
|
|
220
|
+
b = r < 184467440737095517;
|
|
221
|
+
s = s * 2 + (b ? 1 : 0);
|
|
222
|
+
if (b) significand = r;
|
|
223
|
+
|
|
224
|
+
r = rotr64(significand * 14757395258967641293, 1);
|
|
225
|
+
b = r < 1844674407370955162;
|
|
226
|
+
s = s * 2 + (b ? 1 : 0);
|
|
227
|
+
if (b) significand = r;
|
|
228
|
+
|
|
229
|
+
exponent += s;
|
|
230
|
+
_dbRemovedExponent = exponent;
|
|
231
|
+
return significand;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@inline
|
|
235
|
+
function divideByPow10_64_1(n: u64): u64 {
|
|
236
|
+
return umul128_upper64(n, 1844674407370955162);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@inline
|
|
240
|
+
function divideByPow10_64_3(n: u64): u64 {
|
|
241
|
+
return umul128_upper64(n, 4722366482869645214) >>> 8;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@inline
|
|
245
|
+
function checkDivisibilityAndDivideByPow10_64_2(n: u64): u64 {
|
|
246
|
+
const prod = <u32>(n * 656);
|
|
247
|
+
return (<u64>(prod >>> 16) << 32) | (((prod & 0xFFFF) < 656) ? 1 : 0);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@inline
|
|
251
|
+
function genExponent(buffer: usize, k: i32): i32 {
|
|
252
|
+
let negative = k < 0;
|
|
253
|
+
if (negative) k = -k;
|
|
254
|
+
let decimals = decimalCount32(<u32>k) + 1;
|
|
255
|
+
utoa32_dec_core(buffer, <u32>k, <usize>decimals);
|
|
256
|
+
store<u16>(buffer, negative ? CHAR_MINUS : CHAR_PLUS);
|
|
257
|
+
return decimals;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function prettify(buffer: usize, length: i32, k: i32): i32 {
|
|
261
|
+
const fast = prettifyFast(buffer, length, k);
|
|
262
|
+
if (fast >= 0) return fast;
|
|
263
|
+
|
|
264
|
+
if (!k) {
|
|
265
|
+
const tail = buffer + (<usize>length << 1);
|
|
266
|
+
store<u16>(tail, CHAR_DOT);
|
|
267
|
+
store<u16>(tail, CHAR_0, 2);
|
|
268
|
+
return length + 2;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const kk = length + k;
|
|
272
|
+
if (length <= kk && kk <= 21) {
|
|
273
|
+
for (let i = length; i < kk; ++i) store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
274
|
+
const tail = buffer + (<usize>kk << 1);
|
|
275
|
+
store<u16>(tail, CHAR_DOT);
|
|
276
|
+
store<u16>(tail, CHAR_0, 2);
|
|
277
|
+
return kk + 2;
|
|
278
|
+
} else if (kk > 0 && kk <= 21) {
|
|
279
|
+
const ptr = buffer + (<usize>kk << 1);
|
|
280
|
+
memory.copy(ptr + 2, ptr, <usize>(-k) << 1);
|
|
281
|
+
store<u16>(buffer + (<usize>kk << 1), CHAR_DOT);
|
|
282
|
+
return length + 1;
|
|
283
|
+
} else if (-6 < kk && kk <= 0) {
|
|
284
|
+
const offset = 2 - kk;
|
|
285
|
+
memory.copy(buffer + (<usize>offset << 1), buffer, <usize>length << 1);
|
|
286
|
+
store<u16>(buffer, CHAR_0);
|
|
287
|
+
store<u16>(buffer, CHAR_DOT, 2);
|
|
288
|
+
for (let i = 2; i < offset; ++i) store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
289
|
+
return length + offset;
|
|
290
|
+
} else if (length == 1) {
|
|
291
|
+
store<u16>(buffer, CHAR_E, 2);
|
|
292
|
+
length = genExponent(buffer + 4, kk - 1);
|
|
293
|
+
return length + 2;
|
|
294
|
+
} else {
|
|
295
|
+
const len = <usize>length << 1;
|
|
296
|
+
memory.copy(buffer + 4, buffer + 2, len - 2);
|
|
297
|
+
store<u16>(buffer, CHAR_DOT, 2);
|
|
298
|
+
store<u16>(buffer + len, CHAR_E, 2);
|
|
299
|
+
length += genExponent(buffer + len + 4, kk - 1);
|
|
300
|
+
return length + 2;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function prettifyFast(buffer: usize, length: i32, k: i32): i32 {
|
|
305
|
+
if (k == 0) {
|
|
306
|
+
const tail = buffer + (<usize>length << 1);
|
|
307
|
+
store<u16>(tail, CHAR_DOT);
|
|
308
|
+
store<u16>(tail, CHAR_0, 2);
|
|
309
|
+
return length + 2;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const kk = length + k;
|
|
313
|
+
if (length <= kk && kk <= 21) {
|
|
314
|
+
for (let i = length; i < kk; ++i) {
|
|
315
|
+
store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
316
|
+
}
|
|
317
|
+
const tail = buffer + (<usize>kk << 1);
|
|
318
|
+
store<u16>(tail, CHAR_DOT);
|
|
319
|
+
store<u16>(tail, CHAR_0, 2);
|
|
320
|
+
return kk + 2;
|
|
321
|
+
} else if (kk > 0 && kk <= 21) {
|
|
322
|
+
const ptr = buffer + (<usize>kk << 1);
|
|
323
|
+
memory.copy(ptr + 2, ptr, <usize>(length - kk) << 1);
|
|
324
|
+
store<u16>(buffer + (<usize>kk << 1), CHAR_DOT);
|
|
325
|
+
return length + 1;
|
|
326
|
+
} else if (-6 < kk && kk <= 0) {
|
|
327
|
+
const offset = 2 - kk;
|
|
328
|
+
memory.copy(buffer + (<usize>offset << 1), buffer, <usize>length << 1);
|
|
329
|
+
store<u16>(buffer, CHAR_0);
|
|
330
|
+
store<u16>(buffer, CHAR_DOT, 2);
|
|
331
|
+
for (let i = 2; i < offset; ++i) {
|
|
332
|
+
store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
333
|
+
}
|
|
334
|
+
return length + offset;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return -1;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function dragonboxToDecimalF32(binarySignificand: u32, binaryExponent: i32): u32 {
|
|
341
|
+
const isEven = (binarySignificand & 1) == 0;
|
|
342
|
+
let twoFc = binarySignificand << 1;
|
|
343
|
+
|
|
344
|
+
if (binaryExponent != 0) {
|
|
345
|
+
binaryExponent += -150;
|
|
346
|
+
if (twoFc == 0) {
|
|
347
|
+
const minusK = floor_log10_pow2_minus_log10_4_over_3(binaryExponent);
|
|
348
|
+
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
349
|
+
const cache = load<u64>(DRAGONBOX_F32_CACHE + (<usize>(31 - minusK) << 3));
|
|
350
|
+
let xi = computeLeftEndpointShorter32(cache, beta);
|
|
351
|
+
const zi = computeRightEndpointShorter32(cache, beta);
|
|
352
|
+
if (!(binaryExponent >= 2 && binaryExponent <= 3)) ++xi;
|
|
353
|
+
let decimalSignificand = divideByPow10_32_1(zi);
|
|
354
|
+
if (decimalSignificand * 10 >= xi) {
|
|
355
|
+
let decimalExponent = minusK + 1;
|
|
356
|
+
decimalSignificand = removeTrailingZeros32(decimalSignificand);
|
|
357
|
+
decimalExponent += _dbRemovedExponent;
|
|
358
|
+
_dbK = decimalExponent;
|
|
359
|
+
return decimalSignificand;
|
|
360
|
+
}
|
|
361
|
+
decimalSignificand = computeRoundUpShorter32(cache, beta);
|
|
362
|
+
if ((decimalSignificand & 1) != 0 && binaryExponent == -35) --decimalSignificand;
|
|
363
|
+
else if (decimalSignificand < xi) ++decimalSignificand;
|
|
364
|
+
_dbK = minusK;
|
|
365
|
+
return decimalSignificand;
|
|
366
|
+
}
|
|
367
|
+
twoFc |= 1 << 24;
|
|
368
|
+
} else {
|
|
369
|
+
binaryExponent = -149;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const minusK = floor_log10_pow2(binaryExponent) - 1;
|
|
373
|
+
const cache = load<u64>(DRAGONBOX_F32_CACHE + (<usize>(31 - minusK) << 3));
|
|
374
|
+
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
375
|
+
const deltai = <u32>(cache >>> (63 - beta));
|
|
376
|
+
|
|
377
|
+
computeMul32(<u32>((twoFc | 1) << beta), cache);
|
|
378
|
+
let decimalSignificand = divideByPow10_32_2(_dbMulInteger32);
|
|
379
|
+
let r = _dbMulInteger32 - decimalSignificand * 100;
|
|
380
|
+
|
|
381
|
+
if (r < deltai) {
|
|
382
|
+
if ((r | (_dbMulIsInteger ? 0 : 1) | (isEven ? 1 : 0)) == 0) {
|
|
383
|
+
--decimalSignificand;
|
|
384
|
+
r = 100;
|
|
385
|
+
} else {
|
|
386
|
+
let decimalExponent = minusK + 2;
|
|
387
|
+
decimalSignificand = removeTrailingZeros32(decimalSignificand);
|
|
388
|
+
decimalExponent += _dbRemovedExponent;
|
|
389
|
+
_dbK = decimalExponent;
|
|
390
|
+
return decimalSignificand;
|
|
391
|
+
}
|
|
392
|
+
} else if (r == deltai) {
|
|
393
|
+
computeMulParity32(twoFc - 1, cache, beta);
|
|
394
|
+
if (_dbParity || (_dbMulIsInteger && isEven)) {
|
|
395
|
+
let decimalExponent = minusK + 2;
|
|
396
|
+
decimalSignificand = removeTrailingZeros32(decimalSignificand);
|
|
397
|
+
decimalExponent += _dbRemovedExponent;
|
|
398
|
+
_dbK = decimalExponent;
|
|
399
|
+
return decimalSignificand;
|
|
400
|
+
}
|
|
401
|
+
} else if (r < deltai) {
|
|
402
|
+
let decimalExponent = minusK + 2;
|
|
403
|
+
decimalSignificand = removeTrailingZeros32(decimalSignificand);
|
|
404
|
+
decimalExponent += _dbRemovedExponent;
|
|
405
|
+
_dbK = decimalExponent;
|
|
406
|
+
return decimalSignificand;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
decimalSignificand *= 10;
|
|
410
|
+
let dist = r - (deltai >>> 1) + 5;
|
|
411
|
+
const approxYParity = ((dist ^ 5) & 1) != 0;
|
|
412
|
+
let packedDiv = checkDivisibilityAndDivideByPow10_32_1(dist);
|
|
413
|
+
dist = <u32>(packedDiv >>> 32);
|
|
414
|
+
decimalSignificand += dist;
|
|
415
|
+
|
|
416
|
+
if ((packedDiv & 1) != 0) {
|
|
417
|
+
computeMulParity32(twoFc, cache, beta);
|
|
418
|
+
if (_dbParity != approxYParity) --decimalSignificand;
|
|
419
|
+
else if ((decimalSignificand & 1) != 0 && _dbMulIsInteger) --decimalSignificand;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
_dbK = minusK + 1;
|
|
423
|
+
return decimalSignificand;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function dragonboxToDecimalF64(binarySignificand: u64, binaryExponent: i32): u64 {
|
|
427
|
+
const isEven = (binarySignificand & 1) == 0;
|
|
428
|
+
let twoFc = binarySignificand << 1;
|
|
429
|
+
|
|
430
|
+
if (binaryExponent != 0) {
|
|
431
|
+
binaryExponent += -1075;
|
|
432
|
+
if (twoFc == 0) {
|
|
433
|
+
const minusK = floor_log10_pow2_minus_log10_4_over_3(binaryExponent);
|
|
434
|
+
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
435
|
+
const idx = <usize>(292 - minusK) << 4;
|
|
436
|
+
const cacheHigh = load<u64>(DRAGONBOX_F64_CACHE + idx);
|
|
437
|
+
const cacheLow = load<u64>(DRAGONBOX_F64_CACHE + idx + 8);
|
|
438
|
+
let xi = computeLeftEndpointShorter64(cacheHigh, beta);
|
|
439
|
+
const zi = computeRightEndpointShorter64(cacheHigh, beta);
|
|
440
|
+
if (!(binaryExponent >= 2 && binaryExponent <= 3)) ++xi;
|
|
441
|
+
let decimalSignificand = divideByPow10_64_1(zi);
|
|
442
|
+
if (decimalSignificand * 10 >= xi) {
|
|
443
|
+
let decimalExponent = minusK + 1;
|
|
444
|
+
decimalSignificand = removeTrailingZeros64(decimalSignificand);
|
|
445
|
+
decimalExponent += _dbRemovedExponent;
|
|
446
|
+
_dbK = decimalExponent;
|
|
447
|
+
return decimalSignificand;
|
|
448
|
+
}
|
|
449
|
+
decimalSignificand = computeRoundUpShorter64(cacheHigh, beta);
|
|
450
|
+
if ((decimalSignificand & 1) != 0 && binaryExponent == -77) --decimalSignificand;
|
|
451
|
+
else if (decimalSignificand < xi) ++decimalSignificand;
|
|
452
|
+
_dbK = minusK;
|
|
453
|
+
return decimalSignificand;
|
|
454
|
+
}
|
|
455
|
+
twoFc |= (<u64>1) << 53;
|
|
456
|
+
} else {
|
|
457
|
+
binaryExponent = -1074;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const minusK = floor_log10_pow2(binaryExponent) - 2;
|
|
461
|
+
const idx = <usize>(292 - minusK) << 4;
|
|
462
|
+
const cacheHigh = load<u64>(DRAGONBOX_F64_CACHE + idx);
|
|
463
|
+
const cacheLow = load<u64>(DRAGONBOX_F64_CACHE + idx + 8);
|
|
464
|
+
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
465
|
+
const deltai = cacheHigh >>> (63 - beta);
|
|
466
|
+
|
|
467
|
+
computeMul64((twoFc | 1) << beta, cacheHigh, cacheLow);
|
|
468
|
+
let decimalSignificand = divideByPow10_64_3(_dbMulInteger64);
|
|
469
|
+
let r = _dbMulInteger64 - decimalSignificand * 1000;
|
|
470
|
+
|
|
471
|
+
if (r < deltai) {
|
|
472
|
+
if ((r | (_dbMulIsInteger ? 0 : 1) | (isEven ? 1 : 0)) == 0) {
|
|
473
|
+
--decimalSignificand;
|
|
474
|
+
r = 1000;
|
|
475
|
+
} else {
|
|
476
|
+
let decimalExponent = minusK + 3;
|
|
477
|
+
decimalSignificand = removeTrailingZeros64(decimalSignificand);
|
|
478
|
+
decimalExponent += _dbRemovedExponent;
|
|
479
|
+
_dbK = decimalExponent;
|
|
480
|
+
return decimalSignificand;
|
|
481
|
+
}
|
|
482
|
+
} else if (r == deltai) {
|
|
483
|
+
computeMulParity64(twoFc - 1, cacheHigh, cacheLow, beta);
|
|
484
|
+
if (_dbParity || (_dbMulIsInteger && isEven)) {
|
|
485
|
+
let decimalExponent = minusK + 3;
|
|
486
|
+
decimalSignificand = removeTrailingZeros64(decimalSignificand);
|
|
487
|
+
decimalExponent += _dbRemovedExponent;
|
|
488
|
+
_dbK = decimalExponent;
|
|
489
|
+
return decimalSignificand;
|
|
490
|
+
}
|
|
491
|
+
} else if (r < deltai) {
|
|
492
|
+
let decimalExponent = minusK + 3;
|
|
493
|
+
decimalSignificand = removeTrailingZeros64(decimalSignificand);
|
|
494
|
+
decimalExponent += _dbRemovedExponent;
|
|
495
|
+
_dbK = decimalExponent;
|
|
496
|
+
return decimalSignificand;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
decimalSignificand *= 10;
|
|
500
|
+
let dist = r - (deltai >>> 1) + 50;
|
|
501
|
+
const approxYParity = ((dist ^ 50) & 1) != 0;
|
|
502
|
+
let packedDiv = checkDivisibilityAndDivideByPow10_64_2(dist);
|
|
503
|
+
dist = packedDiv >>> 32;
|
|
504
|
+
decimalSignificand += dist;
|
|
505
|
+
|
|
506
|
+
if ((packedDiv & 1) != 0) {
|
|
507
|
+
computeMulParity64(twoFc, cacheHigh, cacheLow, beta);
|
|
508
|
+
if (_dbParity != approxYParity) --decimalSignificand;
|
|
509
|
+
else if ((decimalSignificand & 1) != 0 && _dbMulIsInteger) --decimalSignificand;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
_dbK = minusK + 2;
|
|
513
|
+
return decimalSignificand;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function dragonboxCoreF32(buffer: usize, value: f32): u32 {
|
|
517
|
+
let sign = 0;
|
|
518
|
+
if (value < 0) {
|
|
519
|
+
sign = 1;
|
|
520
|
+
value = -value;
|
|
521
|
+
store<u16>(buffer, CHAR_MINUS);
|
|
522
|
+
}
|
|
523
|
+
const digits = dragonboxToDecimalF32(reinterpret<u32>(value) & 0x7FFFFF, (reinterpret<u32>(value) >>> 23) & 0xFF);
|
|
524
|
+
let len = itoa_buffered<u32>(buffer + (<usize>sign << 1), digits);
|
|
525
|
+
return <u32>(prettify(buffer + (<usize>sign << 1), len, _dbK) + sign);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function dragonboxCoreF64(buffer: usize, value: f64): u32 {
|
|
529
|
+
let sign = 0;
|
|
530
|
+
if (value < 0) {
|
|
531
|
+
sign = 1;
|
|
532
|
+
value = -value;
|
|
533
|
+
store<u16>(buffer, CHAR_MINUS);
|
|
534
|
+
}
|
|
535
|
+
const bits = reinterpret<u64>(value);
|
|
536
|
+
const digits = dragonboxToDecimalF64(bits & 0x000FFFFFFFFFFFFF, <i32>((bits >>> 52) & 0x7FF));
|
|
537
|
+
let len = itoa_buffered<u64>(buffer + (<usize>sign << 1), digits);
|
|
538
|
+
return <u32>(prettify(buffer + (<usize>sign << 1), len, _dbK) + sign);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export function dragonbox_f32_buffered(buffer: usize, value: f32): u32 {
|
|
542
|
+
if (value == 0) {
|
|
543
|
+
store<u16>(buffer, CHAR_0);
|
|
544
|
+
store<u16>(buffer, CHAR_DOT, 2);
|
|
545
|
+
store<u16>(buffer, CHAR_0, 4);
|
|
546
|
+
return 3;
|
|
547
|
+
}
|
|
548
|
+
if (!isFinite(value)) {
|
|
549
|
+
if (isNaN(value)) {
|
|
550
|
+
store<u16>(buffer, 78);
|
|
551
|
+
store<u16>(buffer, 97, 2);
|
|
552
|
+
store<u16>(buffer, 78, 4);
|
|
553
|
+
return 3;
|
|
554
|
+
}
|
|
555
|
+
let sign = value < 0;
|
|
556
|
+
if (sign) {
|
|
557
|
+
store<u16>(buffer, CHAR_MINUS);
|
|
558
|
+
buffer += 2;
|
|
559
|
+
}
|
|
560
|
+
store<u64>(buffer, 0x690066006E0049);
|
|
561
|
+
store<u64>(buffer + 8, 0x7900740069006E);
|
|
562
|
+
return 8 + (sign ? 1 : 0);
|
|
563
|
+
}
|
|
564
|
+
return dragonboxCoreF32(buffer, value);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export function dragonbox_f64_buffered(buffer: usize, value: f64): u32 {
|
|
568
|
+
if (value == 0) {
|
|
569
|
+
store<u16>(buffer, CHAR_0);
|
|
570
|
+
store<u16>(buffer, CHAR_DOT, 2);
|
|
571
|
+
store<u16>(buffer, CHAR_0, 4);
|
|
572
|
+
return 3;
|
|
573
|
+
}
|
|
574
|
+
if (!isFinite(value)) {
|
|
575
|
+
if (isNaN(value)) {
|
|
576
|
+
store<u16>(buffer, 78);
|
|
577
|
+
store<u16>(buffer, 97, 2);
|
|
578
|
+
store<u16>(buffer, 78, 4);
|
|
579
|
+
return 3;
|
|
580
|
+
}
|
|
581
|
+
let sign = value < 0;
|
|
582
|
+
if (sign) {
|
|
583
|
+
store<u16>(buffer, CHAR_MINUS);
|
|
584
|
+
buffer += 2;
|
|
585
|
+
}
|
|
586
|
+
store<u64>(buffer, 0x690066006E0049);
|
|
587
|
+
store<u64>(buffer + 8, 0x7900740069006E);
|
|
588
|
+
return 8 + (sign ? 1 : 0);
|
|
589
|
+
}
|
|
590
|
+
return dragonboxCoreF64(buffer, value);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
export function dragonbox_buffered<T extends number>(buffer: usize, value: T): u32 {
|
|
594
|
+
if (sizeof<T>() == 4) return dragonbox_f32_buffered(buffer, <f32>value);
|
|
595
|
+
return dragonbox_f64_buffered(buffer, <f64>value);
|
|
596
|
+
}
|
package/assembly/util/swar.ts
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode four lowercase ASCII hex digits packed into UTF-16 lanes into one `u16`.
|
|
3
|
+
*
|
|
4
|
+
* The input is a `u64` whose four 16-bit lanes each contain one ASCII hex code
|
|
5
|
+
* unit in the low byte:
|
|
6
|
+
*
|
|
7
|
+
* - lane 0: most-significant hex digit
|
|
8
|
+
* - lane 1: next hex digit
|
|
9
|
+
* - lane 2: next hex digit
|
|
10
|
+
* - lane 3: least-significant hex digit
|
|
11
|
+
*
|
|
12
|
+
* For example, `0x0034_0033_0032_0031` represents the UTF-16 string `"1234"`
|
|
13
|
+
* and decodes to `0x1234`.
|
|
14
|
+
*
|
|
15
|
+
* This helper assumes the digits are already valid lowercase hexadecimal
|
|
16
|
+
* characters in the ranges `0-9` or `a-f`.
|
|
17
|
+
*
|
|
18
|
+
* @param block Packed UTF-16 ASCII hex digits.
|
|
19
|
+
* @returns The decoded 16-bit value.
|
|
20
|
+
*/
|
|
1
21
|
// @ts-expect-error: @inline is a valid decorator
|
|
2
22
|
@inline export function hex4_to_u16_swar(block: u64): u16 {
|
|
3
23
|
// (c & 0xF) + 9 * (c >> 6)
|
|
@@ -5,3 +25,32 @@
|
|
|
5
25
|
|
|
6
26
|
return <u16>(((block >> 0) << 12) | ((block >> 16) << 8) | ((block >> 32) << 4) | (block >> 48));
|
|
7
27
|
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Encode one `u16` into four lowercase ASCII hex digits packed into UTF-16 lanes.
|
|
31
|
+
*
|
|
32
|
+
* The returned `u64` is laid out so it can be written directly as four UTF-16
|
|
33
|
+
* code units:
|
|
34
|
+
*
|
|
35
|
+
* - lane 0: most-significant hex digit
|
|
36
|
+
* - lane 1: next hex digit
|
|
37
|
+
* - lane 2: next hex digit
|
|
38
|
+
* - lane 3: least-significant hex digit
|
|
39
|
+
*
|
|
40
|
+
* Each lane stores the ASCII character in the low byte and zero in the high
|
|
41
|
+
* byte. For example, `0x1234` becomes `0x0034_0033_0032_0031`, which
|
|
42
|
+
* represents the UTF-16 string `"1234"`.
|
|
43
|
+
*
|
|
44
|
+
* This helper is the inverse of {@link hex4_to_u16_swar}.
|
|
45
|
+
*
|
|
46
|
+
* @param code The 16-bit value to encode.
|
|
47
|
+
* @returns Four packed UTF-16 ASCII hex digits.
|
|
48
|
+
*/
|
|
49
|
+
// @ts-expect-error: @inline is a valid decorator
|
|
50
|
+
@inline export function u16_to_hex4_swar(code: u16): u64 {
|
|
51
|
+
let block = (<u64>((code >> 12) & 0xf)) | ((<u64>((code >> 8) & 0xf)) << 16) | ((<u64>((code >> 4) & 0xf)) << 32) | ((<u64>(code & 0xf)) << 48);
|
|
52
|
+
|
|
53
|
+
const alphaMask = ((block + 0x0006_0006_0006_0006) >> 4) & 0x0001_0001_0001_0001;
|
|
54
|
+
block += 0x0030_0030_0030_0030 + alphaMask * 39;
|
|
55
|
+
return block;
|
|
56
|
+
}
|