This commit is contained in:
dcode
2019-03-14 05:11:03 +01:00
parent 6163a73ab5
commit a5e14a0eaa
24 changed files with 739 additions and 102 deletions

View File

@ -42,6 +42,7 @@ function R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3
return p / q;
}
// @ts-ignore: decorator
@inline function expo2(x: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
const // see: musl/src/math/__expo2.c
k = <u32>2043,
@ -50,11 +51,15 @@ function R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3
return NativeMath.exp(x - kln2) * scale * scale;
}
/** @internal */
// @ts-ignore: decorator
@lazy var random_seeded = false;
// @ts-ignore: decorator
@lazy var random_state0_64: u64;
// @ts-ignore: decorator
@lazy var random_state1_64: u64;
// @ts-ignore: decorator
@lazy var random_state0_32: u32;
// @ts-ignore: decorator
@lazy var random_state1_32: u32;
function murmurHash3(h: u64): u64 { // Force all bits of a hash block to avalanche
@ -75,17 +80,25 @@ function splitMix32(h: u32): u32 {
export namespace NativeMath {
// @ts-ignore: decorator
@lazy export const E = reinterpret<f64>(0x4005BF0A8B145769); // 2.7182818284590452354
// @ts-ignore: decorator
@lazy export const LN2 = reinterpret<f64>(0x3FE62E42FEFA39EF); // 0.69314718055994530942
// @ts-ignore: decorator
@lazy export const LN10 = reinterpret<f64>(0x40026BB1BBB55516); // 2.30258509299404568402
// @ts-ignore: decorator
@lazy export const LOG2E = reinterpret<f64>(0x3FF71547652B82FE); // 1.4426950408889634074
// @ts-ignore: decorator
@lazy export const LOG10E = reinterpret<f64>(0x3FDBCB7B1526E50E); // 0.43429448190325182765
// @ts-ignore: decorator
@lazy export const PI = reinterpret<f64>(0x400921FB54442D18); // 3.14159265358979323846
// @ts-ignore: decorator
@lazy export const SQRT1_2 = reinterpret<f64>(0x3FE6A09E667F3BCD); // 0.70710678118654752440
// @ts-ignore: decorator
@lazy export const SQRT2 = reinterpret<f64>(0x3FF6A09E667F3BCD); // 1.41421356237309504880
@inline
export function abs(x: f64): f64 {
// @ts-ignore: decorator
@inline export function abs(x: f64): f64 {
return builtin_abs<f64>(x);
}
@ -346,8 +359,8 @@ export namespace NativeMath {
return t;
}
@inline
export function ceil(x: f64): f64 {
// @ts-ignore: decorator
@inline export function ceil(x: f64): f64 {
return builtin_ceil<f64>(x);
}
@ -497,13 +510,13 @@ export namespace NativeMath {
return (x + y) * twopk;
}
@inline
export function floor(x: f64): f64 {
// @ts-ignore: decorator
@inline export function floor(x: f64): f64 {
return builtin_floor<f64>(x);
}
@inline
export function fround(x: f64): f32 {
// @ts-ignore: decorator
@inline export function fround(x: f64): f32 {
return <f32>x;
}
@ -763,13 +776,13 @@ export namespace NativeMath {
return val_lo + val_hi;
}
@inline
export function max(value1: f64, value2: f64): f64 {
// @ts-ignore: decorator
@inline export function max(value1: f64, value2: f64): f64 {
return builtin_max<f64>(value1, value2);
}
@inline
export function min(value1: f64, value2: f64): f64 {
// @ts-ignore: decorator
@inline export function min(value1: f64, value2: f64): f64 {
return builtin_min<f64>(value1, value2);
}
@ -997,13 +1010,13 @@ export namespace NativeMath {
return reinterpret<f64>(r) - 1;
}
@inline
export function round(x: f64): f64 {
// @ts-ignore: decorator
@inline export function round(x: f64): f64 {
return builtin_copysign<f64>(builtin_floor<f64>(x + 0.5), x);
}
@inline
export function sign(x: f64): f64 {
// @ts-ignore: decorator
@inline export function sign(x: f64): f64 {
if (ASC_SHRINK_LEVEL > 0) {
return builtin_abs(x) > 0 ? builtin_copysign<f64>(1, x) : x;
} else {
@ -1011,10 +1024,11 @@ export namespace NativeMath {
}
}
@inline
export function signbit(x: f64): bool {
// @ts-ignore: decorator
@inline export function signbit(x: f64): bool {
// In ECMAScript all NaN values are indistinguishable from each other
// so we need handle NaN and negative NaN in similar way
// @ts-ignore: type
return <bool>(<i32>(reinterpret<u64>(x) >>> 63) & (x == x));
}
@ -1041,8 +1055,8 @@ export namespace NativeMath {
return t;
}
@inline
export function sqrt(x: f64): f64 {
// @ts-ignore: decorator
@inline export function sqrt(x: f64): f64 {
return builtin_sqrt<f64>(x);
}
@ -1074,8 +1088,8 @@ export namespace NativeMath {
return builtin_copysign<f64>(t, x);
}
@inline
export function trunc(x: f64): f64 {
// @ts-ignore: decorator
@inline export function trunc(x: f64): f64 {
return builtin_trunc<f64>(x);
}
@ -1232,8 +1246,9 @@ export namespace NativeMath {
}
}
/** @internal */
// @ts-ignore: decorator
@lazy var rempio2f_y: f64;
// @ts-ignore: decorator
@lazy const PIO2_TABLE: u64[] = [
0xA2F9836E4E441529,
0xFC2757D1F534DDC0,
@ -1241,7 +1256,6 @@ export namespace NativeMath {
0xFE5163ABDEBBC561
];
/** @internal */
function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
const // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above
pS0 = reinterpret<f32>(0x3E2AAA75), // 1.6666586697e-01f
@ -1253,6 +1267,7 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
return p / q;
}
// @ts-ignore: decorator
@inline function expo2f(x: f32): f32 { // exp(x)/2 for x >= log(DBL_MAX)
const // see: musl/src/math/__expo2f.c
k = <u32>235,
@ -1261,8 +1276,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
return NativeMathf.exp(x - kln2) * scale * scale;
}
@inline /** @internal */
function pio2_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
// @ts-ignore: decorator
@inline function pio2_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
const coeff = reinterpret<f64>(0x3BF921FB54442D18); // π * 0x1p-65 = 8.51530395021638647334e-20
const bits = PIO2_TABLE;
@ -1291,8 +1306,8 @@ function pio2_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob
return q;
}
@inline /** @internal */
function rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
// @ts-ignore: decorator
@inline function rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
const pi2hi = reinterpret<f64>(0x3FF921FB50000000); // 1.57079631090164184570
const pi2lo = reinterpret<f64>(0x3E5110B4611A6263); // 1.58932547735281966916e-8
const _2_pi = reinterpret<f64>(0x3FE45F306DC9C883); // 0.63661977236758134308
@ -1308,8 +1323,8 @@ function rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob
}
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
@inline /** @internal */
function sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c
// @ts-ignore: decorator
@inline function sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c
const S1 = reinterpret<f64>(0xBFC5555554CBAC77); // -0x15555554cbac77.0p-55
const S2 = reinterpret<f64>(0x3F811110896EFBB2); // 0x111110896efbb2.0p-59
const S3 = reinterpret<f64>(0xBF2A00F9E2CAE774); // -0x1a00f9e2cae774.0p-65
@ -1323,8 +1338,8 @@ function sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c
}
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
@inline /** @internal */
function cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c
// @ts-ignore: decorator
@inline function cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c
const C0 = reinterpret<f64>(0xBFDFFFFFFD0C5E81); // -0x1ffffffd0c5e81.0p-54
const C1 = reinterpret<f64>(0x3FA55553E1053A42); // 0x155553e1053a42.0p-57
const C2 = reinterpret<f64>(0xBF56C087E80F1E27); // -0x16c087e80f1e27.0p-62
@ -1337,8 +1352,8 @@ function cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c
}
/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
@inline /** @internal */
function tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c
// @ts-ignore: decorator
@inline function tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c
const T0 = reinterpret<f64>(0x3FD5554D3418C99F); /* 0x15554d3418c99f.0p-54 */
const T1 = reinterpret<f64>(0x3FC112FD38999F72); /* 0x1112fd38999f72.0p-55 */
@ -1360,21 +1375,31 @@ function tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c
export namespace NativeMathf {
// @ts-ignore: decorator
@lazy export const E = <f32>NativeMath.E;
// @ts-ignore: decorator
@lazy export const LN2 = <f32>NativeMath.LN2;
// @ts-ignore: decorator
@lazy export const LN10 = <f32>NativeMath.LN10;
// @ts-ignore: decorator
@lazy export const LOG2E = <f32>NativeMath.LOG2E;
// @ts-ignore: decorator
@lazy export const LOG10E = <f32>NativeMath.LOG10E;
// @ts-ignore: decorator
@lazy export const PI = <f32>NativeMath.PI;
// @ts-ignore: decorator
@lazy export const SQRT1_2 = <f32>NativeMath.SQRT1_2;
// @ts-ignore: decorator
@lazy export const SQRT2 = <f32>NativeMath.SQRT2;
/** Used as return values from Mathf.sincos */
// @ts-ignore: decorator
@lazy export var sincos_sin: f32 = 0;
// @ts-ignore: decorator
@lazy export var sincos_cos: f32 = 0;
@inline
export function abs(x: f32): f32 {
// @ts-ignore: decorator
@inline export function abs(x: f32): f32 {
return builtin_abs<f32>(x);
}
@ -1609,8 +1634,8 @@ export namespace NativeMathf {
return <f32>t;
}
@inline
export function ceil(x: f32): f32 {
// @ts-ignore: decorator
@inline export function ceil(x: f32): f32 {
return builtin_ceil<f32>(x);
}
@ -1685,8 +1710,8 @@ export namespace NativeMathf {
return expo2f(x);
}
@inline
export function floor(x: f32): f32 {
// @ts-ignore: decorator
@inline export function floor(x: f32): f32 {
return builtin_floor<f32>(x);
}
@ -1796,8 +1821,8 @@ export namespace NativeMathf {
return (x + y) * twopk;
}
@inline
export function fround(x: f32): f32 {
// @ts-ignore: decorator
@inline export function fround(x: f32): f32 {
return x;
}
@ -1831,8 +1856,8 @@ export namespace NativeMathf {
return z * builtin_sqrt<f32>(<f32>(<f64>x * x + <f64>y * y));
}
@inline
export function imul(x: f32, y: f32): f32 {
// @ts-ignore: decorator
@inline export function imul(x: f32, y: f32): f32 {
/*
* Wasm (MVP) and JS have different approaches for double->int conversions.
*
@ -2010,13 +2035,13 @@ export namespace NativeMathf {
return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + dk;
}
@inline
export function max(value1: f32, value2: f32): f32 {
// @ts-ignore: decorator
@inline export function max(value1: f32, value2: f32): f32 {
return builtin_max<f32>(value1, value2);
}
@inline
export function min(value1: f32, value2: f32): f32 {
// @ts-ignore: decorator
@inline export function min(value1: f32, value2: f32): f32 {
return builtin_min<f32>(value1, value2);
}
@ -2209,8 +2234,8 @@ export namespace NativeMathf {
return sn * z;
}
@inline
export function seedRandom(value: i64): void {
// @ts-ignore: decorator
@inline export function seedRandom(value: i64): void {
NativeMath.seedRandom(value);
}
@ -2229,13 +2254,13 @@ export namespace NativeMathf {
return reinterpret<f32>((r >> 9) | (127 << 23)) - 1.0;
}
@inline
export function round(x: f32): f32 {
// @ts-ignore: decorator
@inline export function round(x: f32): f32 {
return builtin_copysign<f32>(builtin_floor<f32>(x + 0.5), x);
}
@inline
export function sign(x: f32): f32 {
// @ts-ignore: decorator
@inline export function sign(x: f32): f32 {
if (ASC_SHRINK_LEVEL > 0) {
return builtin_abs(x) > 0 ? builtin_copysign<f32>(1, x) : x;
} else {
@ -2243,8 +2268,9 @@ export namespace NativeMathf {
}
}
@inline
export function signbit(x: f32): bool {
// @ts-ignore: decorator
@inline export function signbit(x: f32): bool {
// @ts-ignore: type
return <bool>((reinterpret<u32>(x) >>> 31) & (x == x));
}
@ -2308,8 +2334,8 @@ export namespace NativeMathf {
return t;
}
@inline
export function sqrt(x: f32): f32 {
// @ts-ignore: decorator
@inline export function sqrt(x: f32): f32 {
return builtin_sqrt<f32>(x);
}
@ -2377,8 +2403,8 @@ export namespace NativeMathf {
return builtin_copysign<f32>(t, x);
}
@inline
export function trunc(x: f32): f32 {
// @ts-ignore: decorator
@inline export function trunc(x: f32): f32 {
return builtin_trunc<f32>(x);
}
@ -2541,12 +2567,12 @@ export namespace NativeMathf {
if (ix <= 0x3f490fda) { /* |x| ~<= π/4 */
if (ix < 0x39800000) { /* |x| < 2**-12 */
sincos_s32 = x;
sincos_c32 = 1;
sincos_sin = x;
sincos_cos = 1;
return;
}
sincos_s32 = sin_kernf(x);
sincos_c32 = cos_kernf(x);
sincos_sin = sin_kernf(x);
sincos_cos = cos_kernf(x);
return;
}
@ -2554,33 +2580,33 @@ export namespace NativeMathf {
if (ix <= 0x407b53d1) { /* |x| ~<= 5π/4 */
if (ix <= 0x4016cbe3) { /* |x| ~<= 3π/4 */
if (sign) {
sincos_s32 = -cos_kernf(x + s1pio2);
sincos_c32 = sin_kernf(x + s1pio2);
sincos_sin = -cos_kernf(x + s1pio2);
sincos_cos = sin_kernf(x + s1pio2);
} else {
sincos_s32 = cos_kernf(s1pio2 - x);
sincos_c32 = sin_kernf(s1pio2 - x);
sincos_sin = cos_kernf(s1pio2 - x);
sincos_cos = sin_kernf(s1pio2 - x);
}
return;
}
/* -sin(x + c) is not correct if x+c could be 0: -0 vs +0 */
sincos_s32 = -sin_kernf(sign ? x + s2pio2 : x - s2pio2);
sincos_c32 = -cos_kernf(sign ? x + s2pio2 : x - s2pio2);
sincos_sin = -sin_kernf(sign ? x + s2pio2 : x - s2pio2);
sincos_cos = -cos_kernf(sign ? x + s2pio2 : x - s2pio2);
return;
}
if (ix <= 0x40e231d5) { /* |x| ~<= 9π/4 */
if (ix <= 0x40afeddf) { /* |x| ~<= 7π/4 */
if (sign) {
sincos_s32 = cos_kernf(x + s3pio2);
sincos_c32 = -sin_kernf(x + s3pio2);
sincos_sin = cos_kernf(x + s3pio2);
sincos_cos = -sin_kernf(x + s3pio2);
} else {
sincos_s32 = -cos_kernf(x - s3pio2);
sincos_c32 = sin_kernf(x - s3pio2);
sincos_sin = -cos_kernf(x - s3pio2);
sincos_cos = sin_kernf(x - s3pio2);
}
return;
}
sincos_s32 = sin_kernf(sign ? x + s4pio2 : x - s4pio2);
sincos_c32 = cos_kernf(sign ? x + s4pio2 : x - s4pio2);
sincos_sin = sin_kernf(sign ? x + s4pio2 : x - s4pio2);
sincos_cos = cos_kernf(sign ? x + s4pio2 : x - s4pio2);
return;
}
}
@ -2588,8 +2614,8 @@ export namespace NativeMathf {
/* sin(Inf or NaN) is NaN */
if (ix >= 0x7f800000) {
let xx = x - x;
sincos_s32 = xx;
sincos_c32 = xx;
sincos_sin = xx;
sincos_cos = xx;
return;
}
@ -2601,24 +2627,24 @@ export namespace NativeMathf {
switch (n & 3) {
case 0: {
sincos_s32 = s;
sincos_c32 = c;
sincos_sin = s;
sincos_cos = c;
break;
}
case 1: {
sincos_s32 = c;
sincos_c32 = -s;
sincos_sin = c;
sincos_cos = -s;
break;
}
case 2: {
sincos_s32 = -s;
sincos_c32 = -c;
sincos_sin = -s;
sincos_cos = -c;
break;
}
case 3:
default: {
sincos_s32 = -c;
sincos_c32 = s;
sincos_sin = -c;
sincos_cos = s;
break;
}
}