More math

This commit is contained in:
dcodeIO 2018-03-26 23:46:41 +02:00
parent 792202ac5a
commit e47a130771
7 changed files with 2652 additions and 509 deletions

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

54
std/assembly.d.ts vendored
View File

@ -354,54 +354,106 @@ declare class Set<T> {
}
interface IMath<T> {
/** The base of natural logarithms, e, approximately 2.718. */
readonly E: T;
/** The natural logarithm of 2, approximately 0.693. */
readonly LN2: T;
/** The natural logarithm of 10, approximately 2.302. */
readonly LN10: T;
/** The base 2 logarithm of e, approximately 1.442. */
readonly LOG2E: T;
/** The base 10 logarithm of e, approximately 0.434. */
readonly LOG10E: T;
/** The ratio of the circumference of a circle to its diameter, approximately 3.14159. */
readonly PI: T;
/** The square root of 1/2, approximately 0.707. */
readonly SQRT1_2: T;
/** The square root of 2, approximately 1.414. */
readonly SQRT2: T;
/** Returns the absolute value of `x`. */
abs(x: T): T;
/** Returns the arccosine (in radians) of `x`. */
acos(x: T): T;
/** Returns the hyperbolic arc-cosine of `x`. */
acosh(x: T): T;
/** Returns the arcsine (in radians) of `x` */
asin(x: T): T;
/** Returns the hyperbolic arcsine of `x`. */
asinh(x: T): T;
/** Returns the arctangent (in radians) of `x`. */
atan(x: T): T;
/** Returns the arctangent of the quotient of its arguments. */
atan2(y: T, x: T): T;
/** Returns the hyperbolic arctangent of `x`. */
atanh(x: T): T;
/** Returns the cube root of `x`. */
cbrt(x: T): T;
/** Returns the smallest integer greater than or equal to `x`. */
ceil(x: T): T;
/** Returns the number of leading zero bits in the 32-bit binary representation of `x`. */
clz32(x: T): i32;
/** Returns the cosine (in radians) of `x`. */
cos(x: T): T;
/** Returns the hyperbolic cosine of `x`. */
cosh(x: T): T;
/** Returns e to the power of `x`. */
exp(x: T): T;
/** Returns e to the power of `x`, minus 1. */
expm1(x: T): T;
/** Returns the largest integer less than or equal to `x`. */
floor(x: T): T;
/** Returns the nearest 32-bit single precision float representation of `x`. */
fround(x: T): f32;
/** Returns the square root of the sum of squares of its arguments. */
hypot(value1: T, value2: T): T; // TODO: rest
/** Returns the result of the C-like 32-bit multiplication of `a` and `b`. */
imul(a: T, b: T): i32;
/** Returns the natural logarithm (base e) of `x`. */
log(x: T): T;
/** Returns the base 10 logarithm of `x`. */
log10(x: T): T;
/** Returns the natural logarithm (base e) of 1 + `x`. */
log1p(x: T): T;
/** Returns the base 2 logarithm of `x`. */
log2(x: T): T;
/** Returns the largest-valued number of its arguments. */
max(value1: T, value2: T): T; // TODO: rest
/** Returns the lowest-valued number of its arguments. */
min(value1: T, value2: T): T; // TODO: rest
/** Returns `base` to the power of `exponent`. */
pow(base: T, exponent: T): T;
/** Returns a pseudo-random number in the range from 0.0 inclusive up to but not including 1.0. */
random(): T;
/** Returns the value of `x` rounded to the nearest integer. */
round(x: T): T;
/** Returns the sign of `x`, indicating whether the number is positive, negative or zero. */
sign(x: T): T;
/** Returns the sine of `x`. */
sin(x: T): T;
/** Returns the hyperbolic sine of `x`. */
sinh(x: T): T;
/** Returns the square root of `x`. */
sqrt(x: T): T;
/** Returns the tangent of `x`. */
tan(x: T): T;
/** Returns the hyperbolic tangent of `x`. */
tanh(x: T): T;
/** Returns the integer part of `x` by removing any fractional digits. */
trunc(x: T): T;
}
interface ISeedRandom {
/** Seeds the random number generator. */
seedRandom(value: i64): void;
}
/** Double precision math imported from JavaScript. */
declare const JSMath: IMath<f64>;
declare const NativeMath: IMath<f64>;
/** Double precision math implemented natively. */
declare const NativeMath: IMath<f64> & ISeedRandom;
/** Single precision math implemented natively. */
declare const NativeMathf: IMath<f32>;
/** Alias of {@link NativeMath} or {@link JSMath} respectively. Defaults to `NativeMath`. */
declare const Math: IMath<f64>;
// Internal decorators

View File

@ -58,7 +58,7 @@ import {
trunc as builtin_trunc
} from "./builtins";
// NativeMath/NativeMathf.log/exp/pow
// NativeMath/NativeMathf.cbrt/exp/log/pow
// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
// Developed at SunPro, a Sun Microsystems, Inc. business.
// Permission to use, copy, modify, and distribute this
@ -80,6 +80,110 @@ export namespace NativeMath {
return builtin_abs(x);
}
export function acos(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function acosh(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function asin(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function asinh(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function atan(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function atanh(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function atan2(y: f64, x: f64): f64 {
unreachable(); // TOOD
return 0;
}
export function cbrt(x: f64): f64 { // based on musl's implementation of cbrt
const
B1 = <u32>715094163, // B1 = (1023-1023/3-0.03306235651)*2**20
B2 = <u32>696219795, // B2 = (1023-1023/3-54/3-0.03306235651)*2**20
// |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]).
P0 = 1.87595182427177009643, // 0x3ffe03e6, 0x0f61e692
P1 = -1.88497979543377169875, // 0xbffe28e0, 0x92f02420
P2 = 1.621429720105354466140, // 0x3ff9f160, 0x4a49d6c2
P3 = -0.758397934778766047437, // 0xbfe844cb, 0xbee751d9
P4 = 0.145996192886612446982, // 0x3fc2b000, 0xd4e4edd7
Ox1p54 = 18014398509481984.0;
var __u = reinterpret<u64>(x);
var hx = <u32>(__u >> 32) & 0x7fffffff;
if (hx >= 0x7ff00000) return x + x; // cbrt(NaN,INF) is itself
// Rough cbrt to 5 bits:
// cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3)
// where e is integral and >= 0, m is real and in [0, 1), and "/" and
// "%" are integer division and modulus with rounding towards minus
// infinity. The RHS is always >= the LHS and has a maximum relative
// error of about 1 in 16. Adding a bias of -0.03306235651 to the
// (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE
// floating point representation, for finite positive normal values,
// ordinary integer divison of the value in bits magically gives
// almost exactly the RHS of the above provided we first subtract the
// exponent bias (1023 for doubles) and later add it back. We do the
// subtraction virtually to keep e >= 0 so that ordinary integer
// division rounds towards minus infinity; this is also efficient.
if (hx < 0x00100000) { // zero or subnormal?
__u = reinterpret<u64>(x * Ox1p54);
hx = <u32>(__u >> 32) & 0x7fffffff;
if (hx == 0) return x; // cbrt(0) is itself
hx = hx / 3 + B2;
} else {
hx = hx / 3 + B1;
}
__u &= 1 << 63;
__u |= <u64>hx << 32;
var t = reinterpret<f64>(__u);
// New cbrt to 23 bits:
// cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x)
// where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r)
// to within 2**-23.5 when |r - 1| < 1/10. The rough approximation
// has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this
// gives us bounds for r = t**3/x.
var r = (t * t) * (t / x);
t = t * ((P0 + r * (P1 + r * P2)) + ((r * r) * r) * (P3 + r * P4));
// Round t away from zero to 23 bits (sloppily except for ensuring that
// the result is larger in magnitude than cbrt(x) but not much more than
// 2 23-bit ulps larger). With rounding towards zero, the error bound
// would be ~5/6 instead of ~4/6. With a maximum error of 2 23-bit ulps
// in the rounded t, the infinite-precision error in the Newton
// approximation barely affects third digit in the final error
// 0.667; the error in the rounded t can be up to about 3 23-bit ulps
// before the final error is larger than 0.667 ulps.
t = reinterpret<f64>((reinterpret<u64>(t) + 0x80000000) & 0xffffffffc0000000);
// one step Newton iteration to 53 bits with error < 0.667 ulps
var s = t * t; // t*t is exact
r = x / s; // error <= 0.5 ulps; |r| < |t|
var w = t + t; // t+t is exact
r = (r - t) / (w + r); // r-t is exact; w+r ~= 3*t
t = t + t * r; // error <= 0.5 + 0.5/3 + epsilon
return t;
}
export function ceil(x: f64): f64 {
return builtin_ceil(x);
}
@ -88,6 +192,16 @@ export namespace NativeMath {
return builtin_clz(<i32>x);
}
export function cos(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function cosh(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function exp(x: f64): f64 { // based on musl's implementation of exp
const
ln2hi = 6.93147180369123816490e-01, // 0x3fe62e42, 0xfee00000
@ -147,6 +261,11 @@ export namespace NativeMath {
return scalbn(y, k);
}
export function expm1(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function floor(x: f64): f64 {
return builtin_floor(x);
}
@ -155,6 +274,11 @@ export namespace NativeMath {
return <f32>x;
}
export function hypot(value1: f64, value2: f64): f64 { // TODO: rest
unreachable(); // TODO
return 0;
}
export function imul(x: f64, y: f64): i32 {
return <i32>x * <i32>y;
}
@ -205,13 +329,22 @@ export namespace NativeMath {
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
}
// export function log2(x: f64): f64 {
// return log(x) / LN2;
// }
export function log10(x: f64): f64 {
// return log(x) / LN10;
unreachable(); // TODO
return 0;
}
// export function log10(x: f64): f64 {
// return log(x) / LN10;
// }
export function log1p(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function log2(x: f64): f64 {
// return log(x) / LN2;
unreachable(); // TODO
return 0;
}
export function max(value1: f64, value2: f64): f64 {
return builtin_max(value1, value2);
@ -451,6 +584,48 @@ export namespace NativeMath {
return s * z;
}
var random_seeded = false;
var random_state0: u64;
var random_state1: u64;
function murmurHash3(h: u64): u64 {
h ^= h >> 33;
h *= 0xFF51AFD7ED558CCD;
h ^= h >> 33;
h *= 0xC4CEB9FE1A85EC53;
h ^= h >> 33;
return h;
}
function xorShift128Plus(): u64 {
var s1 = random_state0;
var s0 = random_state1;
random_state0 = s0;
s1 ^= s1 << 23;
s1 ^= s1 >> 17;
s1 ^= s0;
s1 ^= s0 >> 26;
random_state1 = s1;
return s0 + s1;
}
export function seedRandom(value: i64): void {
assert(value);
random_seeded = true;
random_state0 = murmurHash3(value);
random_state1 = murmurHash3(random_state0);
}
export function random(): f64 { // based on V8's implementation
const
kExponentBits = <u64>0x3FF0000000000000,
kMantissaMask = <u64>0x000FFFFFFFFFFFFF;
if (!random_seeded) unreachable();
var r = (xorShift128Plus() & kMantissaMask) | kExponentBits;
return reinterpret<f64>(r) - 1;
}
export function round(x: f64): f64 {
return builtin_nearest(x);
}
@ -459,13 +634,59 @@ export namespace NativeMath {
return x > 0 ? 1 : x < 0 ? -1 : x;
}
export function sin(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function sinh(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function sqrt(x: f64): f64 {
return builtin_sqrt(x);
}
export function tan(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function tanh(x: f64): f64 {
unreachable(); // TODO
return 0;
}
export function trunc(x: f64): f64 {
return builtin_trunc(x);
}
function scalbn(x: f64, n: i32): f64 { // based on musl's implementation of scalbn
const
Ox1p1023 = 8.98846567431157954e+307,
Ox1p_1022 = 2.22507385850720138e-308;
var y = x;
if (n > 1023) {
y *= Ox1p1023;
n -= 1023;
if (n > 1023) {
y *= Ox1p1023;
n -= 1023;
if (n > 1023) n = 1023;
}
} else if (n < -1022) {
y *= Ox1p_1022;
n += 1022;
if (n < -1022) {
y *= Ox1p_1022;
n += 1022;
if (n < -1022) n = -1022;
}
}
return y * reinterpret<f64>(<u64>(0x3ff + n) << 52);
}
}
export namespace NativeMathf {
@ -483,6 +704,79 @@ export namespace NativeMathf {
return builtin_abs(x);
}
export function acos(x: f32): f32 {
unreachable(); // TOOD
return 0;
}
export function acosh(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function asin(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function asinh(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function atan(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function atanh(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function atan2(y: f32, x: f32): f32 {
unreachable(); // TOOD
return 0;
}
export function cbrt(x: f32): f32 { // based on musl's implementation of cbrtf
const
B1 = <u32>709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */
B2 = <u32>642849266, /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
Ox1p24f = <f32>16777216.0;
var ux = reinterpret<u32>(x);
var hx = ux & 0x7fffffff;
if (hx >= 0x7f800000) return x + x; // cbrt(NaN,INF) is itself
// rough cbrt to 5 bits
if (hx < 0x00800000) { // zero or subnormal?
if (hx == 0) return x; // cbrt(+-0) is itself
ux = reinterpret<u32>(x * Ox1p24f);
hx = ux & 0x7fffffff;
hx = hx / 3 + B2;
} else {
hx = hx / 3 + B1;
}
ux &= 0x80000000;
ux |= hx;
// First step Newton iteration (solving t*t-x/t == 0) to 16 bits. In
// double precision so that its terms can be arranged for efficiency
// without causing overflow or underflow.
var T = <f64>reinterpret<f32>(ux);
var r = T * T * T;
T = T * (<f64>x + x + r) / (x + r + r);
// Second step Newton iteration to 47 bits. In double precision for
// efficiency and accuracy.
r = T * T * T;
T = T * (<f64>x + x + r) / (x + r + r);
// rounding to 24 bits is perfect in round-to-nearest mode
return <f32>T;
}
export function ceil(x: f32): f32 {
return builtin_ceil(x);
}
@ -491,6 +785,16 @@ export namespace NativeMathf {
return builtin_clz(<i32>x);
}
export function cos(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function cosh(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function floor(x: f32): f32 {
return builtin_floor(x);
}
@ -551,7 +855,21 @@ export namespace NativeMathf {
var c = x - xx * (P1 + xx * P2);
var y: f32 = 1 + (x * c / (2 - c) - lo + hi);
if (k == 0) return y;
return scalbnf(y, k);
return scalbn(y, k);
}
export function expm1(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function fround(x: f32): f32 {
return x;
}
export function hypot(value1: f32, value2: f32): f32 { // TODO: rest
unreachable(); // TODO
return 0;
}
export function imul(x: f32, y: f32): i32 {
@ -598,13 +916,22 @@ export namespace NativeMathf {
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
}
// export function log2(x: f32): f32 {
// return log(x) / LN2;
// }
export function log10(x: f32): f32 {
// return log(x) / LN10;
unreachable(); // TODO
return 0;
}
// export function log10(x: f32): f32 {
// return log(x) / LN10;
// }
export function log1p(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function log2(x: f32): f32 {
// return log(x) / LN2;
unreachable(); // TODO
return 0;
}
export function max(value1: f32, value2: f32): f32 {
return builtin_max(value1, value2);
@ -677,10 +1004,10 @@ export namespace NativeMathf {
if (iy == 0x3f800000) return hy >= 0 ? x : 1.0 / x; // y is +-1
if (hy == 0x40000000) return x * x; // y is 2
if (hy == 0x3f000000) { // y is 0.5
if (hx >= 0) return builtin_sqrt<f32>(x); // x >= +0
if (hx >= 0) return builtin_sqrt(x); // x >= +0
}
var ax = builtin_abs<f32>(x);
var ax = builtin_abs(x);
// special value of x
var z: f32;
if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { // x is +-0,+-inf,+-1
@ -822,11 +1149,15 @@ export namespace NativeMathf {
z = 1.0 - (r - z);
j = reinterpret<u32>(z); // GET_FLOAT_WORD(j, z)
j += n << 23;
if ((j >> 23) <= 0) z = scalbnf(z, n); // subnormal output
if ((j >> 23) <= 0) z = scalbn(z, n); // subnormal output
else z = reinterpret<f32>(j); // SET_FLOAT_WORD(z, j)
return sn * z;
}
export function random(): f32 {
return <f32>NativeMath.random();
}
export function round(x: f32): f32 {
return builtin_nearest(x);
}
@ -835,63 +1166,57 @@ export namespace NativeMathf {
return x > 0 ? 1 : x < 0 ? -1 : x;
}
export function sin(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function sinh(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function sqrt(x: f32): f32 {
return builtin_sqrt(x);
}
export function tan(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function tanh(x: f32): f32 {
unreachable(); // TODO
return 0;
}
export function trunc(x: f32): f32 {
return builtin_trunc(x);
}
}
function scalbn(x: f64, n: i32): f64 { // based on musl's implementation of scalbn
const
Ox1p1023 = 8.98846567431157954e+307,
Ox1p_1022 = 2.22507385850720138e-308;
function scalbn(x: f32, n: i32): f32 { // based on musl's implementation of scalbnf
const
Ox1p127f = <f32>1.701411835e+38,
Ox1p_126f = <f32>1.175494351e-38;
var y = x;
if (n > 1023) {
y *= Ox1p1023;
n -= 1023;
if (n > 1023) {
y *= Ox1p1023;
n -= 1023;
if (n > 1023) n = 1023;
}
} else if (n < -1022) {
y *= Ox1p_1022;
n += 1022;
if (n < -1022) {
y *= Ox1p_1022;
n += 1022;
if (n < -1022) n = -1022;
}
}
return y * reinterpret<f64>(<u64>(0x3ff + n) << 52);
}
function scalbnf(x: f32, n: i32): f32 { // based on musl's implementation of scalbnf
const
Ox1p127f = <f32>1.701411835e+38,
Ox1p_126f = <f32>1.175494351e-38;
var y = x;
if (n > 127) {
y *= Ox1p127f;
n -= 127;
var y = x;
if (n > 127) {
y *= Ox1p127f;
n -= 127;
if (n > 127) n = 127;
}
} else if (n < -126) {
y *= Ox1p_126f;
n += 126;
if (n < -126) {
if (n > 127) {
y *= Ox1p127f;
n -= 127;
if (n > 127) n = 127;
}
} else if (n < -126) {
y *= Ox1p_126f;
n += 126;
if (n < -126) n = -126;
if (n < -126) {
y *= Ox1p_126f;
n += 126;
if (n < -126) n = -126;
}
}
return y * reinterpret<f32>(<u32>(0x7f + n) << 23);
}
return y * reinterpret<f32>(<u32>(0x7f + n) << 23);
}

File diff suppressed because it is too large Load Diff

View File

@ -24,84 +24,84 @@ function test_fmod(left: f64, right: f64, expected: f64, error: f64, flags: i32)
}
// sanity
test_fmod(-8.06684839057968084, 4.53566256067686879, -3.53118582990281205, 0.00000000000000000, 0);
test_fmod(4.34523984933830487, -8.88799136300345083, 4.34523984933830487, 0.00000000000000000, 0);
test_fmod(-8.38143342755524934, -2.76360733737958819, -0.0906114154164847641, 0.00000000000000000, 0);
test_fmod(-6.53167358191348413, 4.56753527684274374, -1.96413830507074039, 0.00000000000000000, 0);
test_fmod(9.26705696697258574, 4.81139208435979615, 4.45566488261278959, 0.00000000000000000, 0);
test_fmod(-6.45004555606023633, 0.662071792337673881, -0.491399425021171399, 0.00000000000000000, 0);
test_fmod(7.85889025304169664, 0.0521545267500622481, 0.0357112405323594256, 0.00000000000000000, 0);
test_fmod(-0.792054511984895959, 7.67640268511753998, -0.792054511984895959, 0.00000000000000000, 0);
test_fmod(0.615702673197924044, 2.01190257903248026, 0.615702673197924044, 0.00000000000000000, 0);
test_fmod(-0.558758682360915193, 0.0322398306026380407, -0.0106815621160685006, 0.00000000000000000, 0);
test_fmod(-8.06684839057968084, 4.53566256067686879, -3.53118582990281205, 0.0, 0);
test_fmod(4.34523984933830487, -8.88799136300345083, 4.34523984933830487, 0.0, 0);
test_fmod(-8.38143342755524934, -2.76360733737958819, -0.0906114154164847641, 0.0, 0);
test_fmod(-6.53167358191348413, 4.56753527684274374, -1.96413830507074039, 0.0, 0);
test_fmod(9.26705696697258574, 4.81139208435979615, 4.45566488261278959, 0.0, 0);
test_fmod(-6.45004555606023633, 0.662071792337673881, -0.491399425021171399, 0.0, 0);
test_fmod(7.85889025304169664, 0.0521545267500622481, 0.0357112405323594256, 0.0, 0);
test_fmod(-0.792054511984895959, 7.67640268511753998, -0.792054511984895959, 0.0, 0);
test_fmod(0.615702673197924044, 2.01190257903248026, 0.615702673197924044, 0.0, 0);
test_fmod(-0.558758682360915193, 0.0322398306026380407, -0.0106815621160685006, 0.0, 0);
// special
test_fmod(0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-0.00000000000000000, 1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(0.500000000000000000, 1.00000000000000000, 0.500000000000000000, 0.00000000000000000, 0);
test_fmod(-0.500000000000000000, 1.00000000000000000, -0.500000000000000000, 0.00000000000000000, 0);
test_fmod(1.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-1.00000000000000000, 1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(1.50000000000000000, 1.00000000000000000, 0.500000000000000000, 0.00000000000000000, 0);
test_fmod(-1.50000000000000000, 1.00000000000000000, -0.500000000000000000, 0.00000000000000000, 0);
test_fmod(2.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-2.00000000000000000, 1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(Infinity, 1.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, 1.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(NaN, 1.00000000000000000, NaN, 0.00000000000000000, 0);
test_fmod(0.00000000000000000, -1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-0.00000000000000000, -1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(0.500000000000000000, -1.00000000000000000, 0.500000000000000000, 0.00000000000000000, 0);
test_fmod(-0.500000000000000000, -1.00000000000000000, -0.500000000000000000, 0.00000000000000000, 0);
test_fmod(1.00000000000000000, -1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-1.00000000000000000, -1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(1.50000000000000000, -1.00000000000000000, 0.500000000000000000, 0.00000000000000000, 0);
test_fmod(-1.50000000000000000, -1.00000000000000000, -0.500000000000000000, 0.00000000000000000, 0);
test_fmod(2.00000000000000000, -1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-2.00000000000000000, -1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(Infinity, -1.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, -1.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(NaN, -1.00000000000000000, NaN, 0.00000000000000000, 0);
test_fmod(0.00000000000000000, 0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(0.00000000000000000, -0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(0.00000000000000000, Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(0.00000000000000000, -Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_fmod(0.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_fmod(-0.00000000000000000, 0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-0.00000000000000000, -0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-0.00000000000000000, Infinity, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-0.00000000000000000, -Infinity, -0.00000000000000000, 0.00000000000000000, 0);
test_fmod(-0.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_fmod(1.00000000000000000, 0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-1.00000000000000000, 0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(Infinity, 0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, 0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(NaN, 0.00000000000000000, NaN, 0.00000000000000000, 0);
test_fmod(-1.00000000000000000, -0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(Infinity, -0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, -0.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(NaN, -0.00000000000000000, NaN, 0.00000000000000000, 0);
test_fmod(Infinity, 2.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(Infinity, -0.500000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(Infinity, NaN, NaN, 0.00000000000000000, 0);
test_fmod(-Infinity, 2.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, -0.500000000000000000, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, NaN, NaN, 0.00000000000000000, 0);
test_fmod(NaN, NaN, NaN, 0.00000000000000000, 0);
test_fmod(1.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_fmod(-1.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_fmod(1.00000000000000000, Infinity, 1.00000000000000000, 0.00000000000000000, 0);
test_fmod(-1.00000000000000000, Infinity, -1.00000000000000000, 0.00000000000000000, 0);
test_fmod(Infinity, Infinity, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, Infinity, NaN, 0.00000000000000000, INVALID);
test_fmod(1.00000000000000000, -Infinity, 1.00000000000000000, 0.00000000000000000, 0);
test_fmod(-1.00000000000000000, -Infinity, -1.00000000000000000, 0.00000000000000000, 0);
test_fmod(Infinity, -Infinity, NaN, 0.00000000000000000, INVALID);
test_fmod(-Infinity, -Infinity, NaN, 0.00000000000000000, INVALID);
test_fmod(1.75000000000000000, 0.500000000000000000, 0.250000000000000000, 0.00000000000000000, 0);
test_fmod(-1.75000000000000000, 0.500000000000000000, -0.250000000000000000, 0.00000000000000000, 0);
test_fmod(1.75000000000000000, -0.500000000000000000, 0.250000000000000000, 0.00000000000000000, 0);
test_fmod(-1.75000000000000000, -0.500000000000000000, -0.250000000000000000, 0.00000000000000000, 0);
test_fmod(0.0, 1.0, 0.0, 0.0, 0);
test_fmod(-0.0, 1.0, -0.0, 0.0, 0);
test_fmod(0.5, 1.0, 0.5, 0.0, 0);
test_fmod(-0.5, 1.0, -0.5, 0.0, 0);
test_fmod(1.0, 1.0, 0.0, 0.0, 0);
test_fmod(-1.0, 1.0, -0.0, 0.0, 0);
test_fmod(1.5, 1.0, 0.5, 0.0, 0);
test_fmod(-1.5, 1.0, -0.5, 0.0, 0);
test_fmod(2.0, 1.0, 0.0, 0.0, 0);
test_fmod(-2.0, 1.0, -0.0, 0.0, 0);
test_fmod(Infinity, 1.0, NaN, 0.0, INVALID);
test_fmod(-Infinity, 1.0, NaN, 0.0, INVALID);
test_fmod(NaN, 1.0, NaN, 0.0, 0);
test_fmod(0.0, -1.0, 0.0, 0.0, 0);
test_fmod(-0.0, -1.0, -0.0, 0.0, 0);
test_fmod(0.5, -1.0, 0.5, 0.0, 0);
test_fmod(-0.5, -1.0, -0.5, 0.0, 0);
test_fmod(1.0, -1.0, 0.0, 0.0, 0);
test_fmod(-1.0, -1.0, -0.0, 0.0, 0);
test_fmod(1.5, -1.0, 0.5, 0.0, 0);
test_fmod(-1.5, -1.0, -0.5, 0.0, 0);
test_fmod(2.0, -1.0, 0.0, 0.0, 0);
test_fmod(-2.0, -1.0, -0.0, 0.0, 0);
test_fmod(Infinity, -1.0, NaN, 0.0, INVALID);
test_fmod(-Infinity, -1.0, NaN, 0.0, INVALID);
test_fmod(NaN, -1.0, NaN, 0.0, 0);
test_fmod(0.0, 0.0, NaN, 0.0, INVALID);
test_fmod(0.0, -0.0, NaN, 0.0, INVALID);
test_fmod(0.0, Infinity, 0.0, 0.0, 0);
test_fmod(0.0, -Infinity, 0.0, 0.0, 0);
test_fmod(0.0, NaN, NaN, 0.0, 0);
test_fmod(-0.0, 0.0, NaN, 0.0, INVALID);
test_fmod(-0.0, -0.0, NaN, 0.0, INVALID);
test_fmod(-0.0, Infinity, -0.0, 0.0, 0);
test_fmod(-0.0, -Infinity, -0.0, 0.0, 0);
test_fmod(-0.0, NaN, NaN, 0.0, 0);
test_fmod(1.0, 0.0, NaN, 0.0, INVALID);
test_fmod(-1.0, 0.0, NaN, 0.0, INVALID);
test_fmod(Infinity, 0.0, NaN, 0.0, INVALID);
test_fmod(-Infinity, 0.0, NaN, 0.0, INVALID);
test_fmod(NaN, 0.0, NaN, 0.0, 0);
test_fmod(-1.0, -0.0, NaN, 0.0, INVALID);
test_fmod(Infinity, -0.0, NaN, 0.0, INVALID);
test_fmod(-Infinity, -0.0, NaN, 0.0, INVALID);
test_fmod(NaN, -0.0, NaN, 0.0, 0);
test_fmod(Infinity, 2.0, NaN, 0.0, INVALID);
test_fmod(Infinity, -0.5, NaN, 0.0, INVALID);
test_fmod(Infinity, NaN, NaN, 0.0, 0);
test_fmod(-Infinity, 2.0, NaN, 0.0, INVALID);
test_fmod(-Infinity, -0.5, NaN, 0.0, INVALID);
test_fmod(-Infinity, NaN, NaN, 0.0, 0);
test_fmod(NaN, NaN, NaN, 0.0, 0);
test_fmod(1.0, NaN, NaN, 0.0, 0);
test_fmod(-1.0, NaN, NaN, 0.0, 0);
test_fmod(1.0, Infinity, 1.0, 0.0, 0);
test_fmod(-1.0, Infinity, -1.0, 0.0, 0);
test_fmod(Infinity, Infinity, NaN, 0.0, INVALID);
test_fmod(-Infinity, Infinity, NaN, 0.0, INVALID);
test_fmod(1.0, -Infinity, 1.0, 0.0, 0);
test_fmod(-1.0, -Infinity, -1.0, 0.0, 0);
test_fmod(Infinity, -Infinity, NaN, 0.0, INVALID);
test_fmod(-Infinity, -Infinity, NaN, 0.0, INVALID);
test_fmod(1.75, 0.5, 0.25, 0.0, 0);
test_fmod(-1.75, 0.5, -0.25, 0.0, 0);
test_fmod(1.75, -0.5, 0.25, 0.0, 0);
test_fmod(-1.75, -0.5, -0.25, 0.0, 0);
// ================================ built-in fmodf ================================
@ -110,84 +110,84 @@ function test_fmodf(left: f32, right: f32, expected: f32, error: f32, flags: i32
}
// sanity
test_fmodf(-8.066848755, 4.535662651, -3.531186104, 0.000000000, 0);
test_fmodf(4.345239639, -8.887990952, 4.345239639, 0.000000000, 0);
test_fmodf(-8.381433487, -2.763607264, -0.09061169624, 0.000000000, 0);
test_fmodf(-6.531673431, 4.567535400, -1.964138031, 0.000000000, 0);
test_fmodf(9.267057419, 4.811392307, 4.455665112, 0.000000000, 0);
test_fmodf(-6.450045586, 0.6620717645, -0.4913997054, 0.000000000, 0);
test_fmodf(7.858890057, 0.05215452611, 0.03571113944, 0.000000000, 0);
test_fmodf(-0.7920545340, 7.676402569, -0.7920545340, 0.000000000, 0);
test_fmodf(0.6157026887, 2.011902571, 0.6157026887, 0.000000000, 0);
test_fmodf(-0.5587586761, 0.03223983198, -0.01068153232, 0.000000000, 0);
test_fmodf(-8.066848755, 4.535662651, -3.531186104, 0.0, 0);
test_fmodf(4.345239639, -8.887990952, 4.345239639, 0.0, 0);
test_fmodf(-8.381433487, -2.763607264, -0.09061169624, 0.0, 0);
test_fmodf(-6.531673431, 4.5675354, -1.964138031, 0.0, 0);
test_fmodf(9.267057419, 4.811392307, 4.455665112, 0.0, 0);
test_fmodf(-6.450045586, 0.6620717645, -0.4913997054, 0.0, 0);
test_fmodf(7.858890057, 0.05215452611, 0.03571113944, 0.0, 0);
test_fmodf(-0.7920545340, 7.676402569, -0.7920545340, 0.0, 0);
test_fmodf(0.6157026887, 2.011902571, 0.6157026887, 0.0, 0);
test_fmodf(-0.5587586761, 0.03223983198, -0.01068153232, 0.0, 0);
// special
test_fmodf(0.000000000, 1.000000000, 0.000000000, 0.000000000, 0);
test_fmodf(-0.000000000, 1.000000000, -0.000000000, 0.000000000, 0);
test_fmodf(0.5000000000, 1.000000000, 0.5000000000, 0.000000000, 0);
test_fmodf(-0.5000000000, 1.000000000, -0.5000000000, 0.000000000, 0);
test_fmodf(1.000000000, 1.000000000, 0.000000000, 0.000000000, 0);
test_fmodf(-1.000000000, 1.000000000, -0.000000000, 0.000000000, 0);
test_fmodf(1.500000000, 1.000000000, 0.5000000000, 0.000000000, 0);
test_fmodf(-1.500000000, 1.000000000, -0.5000000000, 0.000000000, 0);
test_fmodf(2.000000000, 1.000000000, 0.000000000, 0.000000000, 0);
test_fmodf(-2.000000000, 1.000000000, -0.000000000, 0.000000000, 0);
test_fmodf(Infinity, 1.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, 1.000000000, NaN, 0.000000000, INVALID);
test_fmodf(NaN, 1.000000000, NaN, 0.000000000, 0);
test_fmodf(0.000000000, -1.000000000, 0.000000000, 0.000000000, 0);
test_fmodf(-0.000000000, -1.000000000, -0.000000000, 0.000000000, 0);
test_fmodf(0.5000000000, -1.000000000, 0.5000000000, 0.000000000, 0);
test_fmodf(-0.5000000000, -1.000000000, -0.5000000000, 0.000000000, 0);
test_fmodf(1.000000000, -1.000000000, 0.000000000, 0.000000000, 0);
test_fmodf(-1.000000000, -1.000000000, -0.000000000, 0.000000000, 0);
test_fmodf(1.500000000, -1.000000000, 0.5000000000, 0.000000000, 0);
test_fmodf(-1.500000000, -1.000000000, -0.5000000000, 0.000000000, 0);
test_fmodf(2.000000000, -1.000000000, 0.000000000, 0.000000000, 0);
test_fmodf(-2.000000000, -1.000000000, -0.000000000, 0.000000000, 0);
test_fmodf(Infinity, -1.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, -1.000000000, NaN, 0.000000000, INVALID);
test_fmodf(NaN, -1.000000000, NaN, 0.000000000, 0);
test_fmodf(0.000000000, 0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(0.000000000, -0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(0.000000000, Infinity, 0.000000000, 0.000000000, 0);
test_fmodf(0.000000000, -Infinity, 0.000000000, 0.000000000, 0);
test_fmodf(0.000000000, NaN, NaN, 0.000000000, 0);
test_fmodf(-0.000000000, 0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-0.000000000, -0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-0.000000000, Infinity, -0.000000000, 0.000000000, 0);
test_fmodf(-0.000000000, -Infinity, -0.000000000, 0.000000000, 0);
test_fmodf(-0.000000000, NaN, NaN, 0.000000000, 0);
test_fmodf(1.000000000, 0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-1.000000000, 0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(Infinity, 0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, 0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(NaN, 0.000000000, NaN, 0.000000000, 0);
test_fmodf(-1.000000000, -0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(Infinity, -0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, -0.000000000, NaN, 0.000000000, INVALID);
test_fmodf(NaN, -0.000000000, NaN, 0.000000000, 0);
test_fmodf(Infinity, 2.000000000, NaN, 0.000000000, INVALID);
test_fmodf(Infinity, -0.5000000000, NaN, 0.000000000, INVALID);
test_fmodf(Infinity, NaN, NaN, 0.000000000, 0);
test_fmodf(-Infinity, 2.000000000, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, -0.5000000000, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, NaN, NaN, 0.000000000, 0);
test_fmodf(NaN, NaN, NaN, 0.000000000, 0);
test_fmodf(1.000000000, NaN, NaN, 0.000000000, 0);
test_fmodf(-1.000000000, NaN, NaN, 0.000000000, 0);
test_fmodf(1.000000000, Infinity, 1.000000000, 0.000000000, 0);
test_fmodf(-1.000000000, Infinity, -1.000000000, 0.000000000, 0);
test_fmodf(Infinity, Infinity, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, Infinity, NaN, 0.000000000, INVALID);
test_fmodf(1.000000000, -Infinity, 1.000000000, 0.000000000, 0);
test_fmodf(-1.000000000, -Infinity, -1.000000000, 0.000000000, 0);
test_fmodf(Infinity, -Infinity, NaN, 0.000000000, INVALID);
test_fmodf(-Infinity, -Infinity, NaN, 0.000000000, INVALID);
test_fmodf(1.750000000, 0.5000000000, 0.2500000000, 0.000000000, 0);
test_fmodf(-1.750000000, 0.5000000000, -0.2500000000, 0.000000000, 0);
test_fmodf(1.750000000, -0.5000000000, 0.2500000000, 0.000000000, 0);
test_fmodf(-1.750000000, -0.5000000000, -0.2500000000, 0.000000000, 0);
test_fmodf(0.0, 1.0, 0.0, 0.0, 0);
test_fmodf(-0.0, 1.0, -0.0, 0.0, 0);
test_fmodf(0.5, 1.0, 0.5, 0.0, 0);
test_fmodf(-0.5, 1.0, -0.5, 0.0, 0);
test_fmodf(1.0, 1.0, 0.0, 0.0, 0);
test_fmodf(-1.0, 1.0, -0.0, 0.0, 0);
test_fmodf(1.5, 1.0, 0.5, 0.0, 0);
test_fmodf(-1.5, 1.0, -0.5, 0.0, 0);
test_fmodf(2.0, 1.0, 0.0, 0.0, 0);
test_fmodf(-2.0, 1.0, -0.0, 0.0, 0);
test_fmodf(Infinity, 1.0, NaN, 0.0, INVALID);
test_fmodf(-Infinity, 1.0, NaN, 0.0, INVALID);
test_fmodf(NaN, 1.0, NaN, 0.0, 0);
test_fmodf(0.0, -1.0, 0.0, 0.0, 0);
test_fmodf(-0.0, -1.0, -0.0, 0.0, 0);
test_fmodf(0.5, -1.0, 0.5, 0.0, 0);
test_fmodf(-0.5, -1.0, -0.5, 0.0, 0);
test_fmodf(1.0, -1.0, 0.0, 0.0, 0);
test_fmodf(-1.0, -1.0, -0.0, 0.0, 0);
test_fmodf(1.5, -1.0, 0.5, 0.0, 0);
test_fmodf(-1.5, -1.0, -0.5, 0.0, 0);
test_fmodf(2.0, -1.0, 0.0, 0.0, 0);
test_fmodf(-2.0, -1.0, -0.0, 0.0, 0);
test_fmodf(Infinity, -1.0, NaN, 0.0, INVALID);
test_fmodf(-Infinity, -1.0, NaN, 0.0, INVALID);
test_fmodf(NaN, -1.0, NaN, 0.0, 0);
test_fmodf(0.0, 0.0, NaN, 0.0, INVALID);
test_fmodf(0.0, -0.0, NaN, 0.0, INVALID);
test_fmodf(0.0, Infinity, 0.0, 0.0, 0);
test_fmodf(0.0, -Infinity, 0.0, 0.0, 0);
test_fmodf(0.0, NaN, NaN, 0.0, 0);
test_fmodf(-0.0, 0.0, NaN, 0.0, INVALID);
test_fmodf(-0.0, -0.0, NaN, 0.0, INVALID);
test_fmodf(-0.0, Infinity, -0.0, 0.0, 0);
test_fmodf(-0.0, -Infinity, -0.0, 0.0, 0);
test_fmodf(-0.0, NaN, NaN, 0.0, 0);
test_fmodf(1.0, 0.0, NaN, 0.0, INVALID);
test_fmodf(-1.0, 0.0, NaN, 0.0, INVALID);
test_fmodf(Infinity, 0.0, NaN, 0.0, INVALID);
test_fmodf(-Infinity, 0.0, NaN, 0.0, INVALID);
test_fmodf(NaN, 0.0, NaN, 0.0, 0);
test_fmodf(-1.0, -0.0, NaN, 0.0, INVALID);
test_fmodf(Infinity, -0.0, NaN, 0.0, INVALID);
test_fmodf(-Infinity, -0.0, NaN, 0.0, INVALID);
test_fmodf(NaN, -0.0, NaN, 0.0, 0);
test_fmodf(Infinity, 2.0, NaN, 0.0, INVALID);
test_fmodf(Infinity, -0.5, NaN, 0.0, INVALID);
test_fmodf(Infinity, NaN, NaN, 0.0, 0);
test_fmodf(-Infinity, 2.0, NaN, 0.0, INVALID);
test_fmodf(-Infinity, -0.5, NaN, 0.0, INVALID);
test_fmodf(-Infinity, NaN, NaN, 0.0, 0);
test_fmodf(NaN, NaN, NaN, 0.0, 0);
test_fmodf(1.0, NaN, NaN, 0.0, 0);
test_fmodf(-1.0, NaN, NaN, 0.0, 0);
test_fmodf(1.0, Infinity, 1.0, 0.0, 0);
test_fmodf(-1.0, Infinity, -1.0, 0.0, 0);
test_fmodf(Infinity, Infinity, NaN, 0.0, INVALID);
test_fmodf(-Infinity, Infinity, NaN, 0.0, INVALID);
test_fmodf(1.0, -Infinity, 1.0, 0.0, 0);
test_fmodf(-1.0, -Infinity, -1.0, 0.0, 0);
test_fmodf(Infinity, -Infinity, NaN, 0.0, INVALID);
test_fmodf(-Infinity, -Infinity, NaN, 0.0, INVALID);
test_fmodf(1.75, 0.5, 0.25, 0.0, 0);
test_fmodf(-1.75, 0.5, -0.25, 0.0, 0);
test_fmodf(1.75, -0.5, 0.25, 0.0, 0);
test_fmodf(-1.75, -0.5, -0.25, 0.0, 0);
// ================================ Math.log ================================
@ -197,26 +197,26 @@ function test_log(value: f64, expected: f64, error: f64, flags: i32): void {
}
// sanity
test_log(-8.06684839057968084, NaN, 0.00000000000000000, INVALID);
test_log(-8.06684839057968084, NaN, 0.0, INVALID);
test_log(4.34523984933830487, 1.46908095842243225, -0.341253340244293213, INEXACT);
test_log(-8.38143342755524934, NaN, 0.00000000000000000, INVALID);
test_log(-6.53167358191348413, NaN, 0.00000000000000000, INVALID);
test_log(-8.38143342755524934, NaN, 0.0, INVALID);
test_log(-6.53167358191348413, NaN, 0.0, INVALID);
test_log(9.26705696697258574, 2.22646584987956153, 0.363811403512954712, INEXACT);
test_log(0.661985898099504477, -0.412511025236513673, -0.291087478399276733, INEXACT);
test_log(-0.406603922385355310, NaN, 0.00000000000000000, INVALID);
test_log(-0.406603922385355310, NaN, 0.0, INVALID);
test_log(0.561759746220724110, -0.576681018319586181, -0.109831996262073517, INEXACT);
test_log(0.774152296591303690, -0.255986659126386518, -0.0579900443553924561, INEXACT);
test_log(-0.678763702639402444, NaN, 0.00000000000000000, INVALID);
test_log(-0.678763702639402444, NaN, 0.0, INVALID);
// special
test_log(0.00000000000000000, -Infinity, 0.00000000000000000, DIVBYZERO);
test_log(-0.00000000000000000, -Infinity, 0.00000000000000000, DIVBYZERO);
test_log(-7.88860905221011805e-31, NaN, 0.00000000000000000, INVALID);
test_log(1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_log(-1.00000000000000000, NaN, 0.00000000000000000, INVALID);
test_log(Infinity, Infinity, 0.00000000000000000, 0);
test_log(-Infinity, NaN, 0.00000000000000000, INVALID);
test_log(NaN, NaN, 0.00000000000000000, 0);
test_log(0.0, -Infinity, 0.0, DIVBYZERO);
test_log(-0.0, -Infinity, 0.0, DIVBYZERO);
test_log(-7.88860905221011805e-31, NaN, 0.0, INVALID);
test_log(1.0, 0.0, 0.0, 0);
test_log(-1.0, NaN, 0.0, INVALID);
test_log(Infinity, Infinity, 0.0, 0);
test_log(-Infinity, NaN, 0.0, INVALID);
test_log(NaN, NaN, 0.0, 0);
// ================================ Mathf.log ================================
@ -225,24 +225,24 @@ function test_logf(value: f32, expected: f32, error: f32, flags: i32): void {
}
// sanity
test_logf(0.000000000, -Infinity, 0.000000000, DIVBYZERO);
test_logf(-0.000000000, -Infinity, 0.000000000, DIVBYZERO);
test_logf(-7.888609052e-31, NaN, 0.000000000, INVALID);
test_logf(1.000000000, 0.000000000, 0.000000000, 0);
test_logf(-1.000000000, NaN, 0.000000000, INVALID);
test_logf(Infinity, Infinity, 0.000000000, 0);
test_logf(-Infinity, NaN, 0.000000000, INVALID);
test_logf(NaN, NaN, 0.000000000, 0);
test_logf(0.0, -Infinity, 0.0, DIVBYZERO);
test_logf(-0.0, -Infinity, 0.0, DIVBYZERO);
test_logf(-7.888609052e-31, NaN, 0.0, INVALID);
test_logf(1.0, 0.0, 0.0, 0);
test_logf(-1.0, NaN, 0.0, INVALID);
test_logf(Infinity, Infinity, 0.0, 0);
test_logf(-Infinity, NaN, 0.0, INVALID);
test_logf(NaN, NaN, 0.0, 0);
// special
test_logf(0.000000000, -Infinity, 0.000000000, DIVBYZERO);
test_logf(-0.000000000, -Infinity, 0.000000000, DIVBYZERO);
test_logf(-7.888609052e-31, NaN, 0.000000000, INVALID);
test_logf(1.000000000, 0.000000000, 0.000000000, 0);
test_logf(-1.000000000, NaN, 0.000000000, INVALID);
test_logf(Infinity, Infinity, 0.000000000, 0);
test_logf(-Infinity, NaN, 0.000000000, INVALID);
test_logf(NaN, NaN, 0.000000000, 0);
test_logf(0.0, -Infinity, 0.0, DIVBYZERO);
test_logf(-0.0, -Infinity, 0.0, DIVBYZERO);
test_logf(-7.888609052e-31, NaN, 0.0, INVALID);
test_logf(1.0, 0.0, 0.0, 0);
test_logf(-1.0, NaN, 0.0, INVALID);
test_logf(Infinity, Infinity, 0.0, 0);
test_logf(-Infinity, NaN, 0.0, INVALID);
test_logf(NaN, NaN, 0.0, 0);
// ================================ Math.exp ================================
@ -264,13 +264,13 @@ test_exp(0.774152296591303690, 2.16875288851292458, -0.299612581729888916, INEXA
test_exp(-0.678763702639402444, 0.507243708940284255, 0.472617387771606445, INEXACT);
// special
test_exp(0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_exp(-0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_exp(1.00000000000000000, 2.71828182845904509, -0.325530737638473511, INEXACT);
test_exp(-1.00000000000000000, 0.367879441171442334, 0.223896518349647522, INEXACT);
test_exp(Infinity, Infinity, 0.00000000000000000, 0);
test_exp(-Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_exp(NaN, NaN, 0.00000000000000000, 0);
test_exp(0.0, 1.0, 0.0, 0);
test_exp(-0.0, 1.0, 0.0, 0);
test_exp(1.0, 2.71828182845904509, -0.325530737638473511, INEXACT);
test_exp(-1.0, 0.367879441171442334, 0.223896518349647522, INEXACT);
test_exp(Infinity, Infinity, 0.0, 0);
test_exp(-Infinity, 0.0, 0.0, 0);
test_exp(NaN, NaN, 0.0, 0);
test_exp(1.03972148895263650, 2.82842915587641119, 0.188030809164047241, INEXACT);
test_exp(-1.03972148895263650, 0.353553136702178472, 0.252727240324020386, INEXACT);
test_exp(1.03972101211547852, 2.82842780717661224, -0.418413937091827393, INEXACT);
@ -295,17 +295,17 @@ test_expf(0.7741522789, 2.168752909, 0.2456246912, INEXACT);
test_expf(-0.6787636876, 0.5072436929, -0.3974292278, INEXACT);
// special
test_expf(0.000000000, 1.000000000, 0.000000000, 0);
test_expf(-0.000000000, 1.000000000, 0.000000000, 0);
test_expf(1.000000000, 2.718281746, -0.3462330997, INEXACT);
test_expf(-1.000000000, 0.3678794503, 0.3070148528, INEXACT);
test_expf(Infinity, Infinity, 0.000000000, 0);
test_expf(-Infinity, 0.000000000, 0.000000000, 0);
test_expf(NaN, NaN, 0.000000000, 0);
test_expf(0.0, 1.0, 0.0, 0);
test_expf(-0.0, 1.0, 0.0, 0);
test_expf(1.0, 2.718281746, -0.3462330997, INEXACT);
test_expf(-1.0, 0.3678794503, 0.3070148528, INEXACT);
test_expf(Infinity, Infinity, 0.0, 0);
test_expf(-Infinity, 0.0, 0.0, 0);
test_expf(NaN, NaN, 0.0, 0);
test_expf(88.72283173, 3.402798519e+38, -0.09067153931, INEXACT);
test_expf(88.72283936, Infinity, 0.000000000, INEXACT|OVERFLOW);
test_expf(88.72283936, Infinity, 0.0, INEXACT|OVERFLOW);
test_expf(-103.9720764, 1.401298464e-45, 0.4999996722, INEXACT|UNDERFLOW);
test_expf(-103.9720840, 0.000000000, -0.4999965131, INEXACT|UNDERFLOW);
test_expf(-103.9720840, 0.0, -0.4999965131, INEXACT|UNDERFLOW);
test_expf(0.3465735614, 1.414213538, 0.1392242163, INEXACT);
test_expf(0.3465735912, 1.414213538, -0.2143291682, INEXACT);
test_expf(0.3465736210, 1.414213657, 0.4321174324, INEXACT);
@ -317,109 +317,109 @@ function test_pow(left: f64, right: f64, expected: f64, error: f64, flags: i32):
}
// sanity
test_pow(-8.06684839057968084, 4.53566256067686879, NaN, 0.00000000000000000, INVALID);
test_pow(-8.06684839057968084, 4.53566256067686879, NaN, 0.0, INVALID);
test_pow(4.34523984933830487, -8.88799136300345083, 0.00000213471188255872853, 0.325016021728515625, INEXACT);
test_pow(-8.38143342755524934, -2.76360733737958819, NaN, 0.00000000000000000, INVALID);
test_pow(-6.53167358191348413, 4.56753527684274374, NaN, 0.00000000000000000, INVALID);
test_pow(-8.38143342755524934, -2.76360733737958819, NaN, 0.0, INVALID);
test_pow(-6.53167358191348413, 4.56753527684274374, NaN, 0.0, INVALID);
test_pow(9.26705696697258574, 4.81139208435979615, 44909.2994151296589, -0.266590803861618042, INEXACT);
test_pow(-6.45004555606023633, 0.662071792337673881, NaN, 0.00000000000000000, INVALID);
test_pow(-6.45004555606023633, 0.662071792337673881, NaN, 0.0, INVALID);
test_pow(7.85889025304169664, 0.0521545267500622481, 1.11351774134586523, -0.371686071157455444, INEXACT);
test_pow(-0.792054511984895959, 7.67640268511753998, NaN, 0.00000000000000000, INVALID);
test_pow(-0.792054511984895959, 7.67640268511753998, NaN, 0.0, INVALID);
test_pow(0.615702673197924044, 2.01190257903248026, 0.376907735213801831, 0.324733018875122070, INEXACT);
test_pow(-0.558758682360915193, 0.0322398306026380407, NaN, 0.00000000000000000, INVALID);
test_pow(-0.558758682360915193, 0.0322398306026380407, NaN, 0.0, INVALID);
// special
test_pow(0.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_pow(0.00000000000000000, Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, 3.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, 2.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, 0.500000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(0.00000000000000000, -0.500000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(0.00000000000000000, -1.00000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(0.00000000000000000, -2.00000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(0.00000000000000000, -3.00000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(0.00000000000000000, -4.00000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(0.00000000000000000, -Infinity, Infinity, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, 3.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, 2.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, 1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, 0.500000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.00000000000000000, -0.500000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(-0.00000000000000000, -1.00000000000000000, -Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(-0.00000000000000000, -2.00000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(-0.00000000000000000, -3.00000000000000000, -Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(-0.00000000000000000, -4.00000000000000000, Infinity, 0.00000000000000000, DIVBYZERO);
test_pow(-0.00000000000000000, -Infinity, Infinity, 0.00000000000000000, 0);
test_pow(NaN, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(Infinity, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-Infinity, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(NaN, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(Infinity, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-Infinity, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, -0.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, Infinity, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, -Infinity, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, 2.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, -1.00000000000000000, -1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, -2.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, -3.00000000000000000, -1.00000000000000000, 0.00000000000000000, 0);
test_pow(-1.00000000000000000, 0.500000000000000000, NaN, 0.00000000000000000, INVALID);
test_pow(1.00000000000000000, NaN, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, Infinity, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, -Infinity, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, 3.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, 0.500000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, -0.500000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(1.00000000000000000, -3.00000000000000000, 1.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, 0.500000000000000000, NaN, 0.00000000000000000, INVALID);
test_pow(-0.500000000000000000, 1.50000000000000000, NaN, 0.00000000000000000, INVALID);
test_pow(-0.500000000000000000, 2.00000000000000000, 0.250000000000000000, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, 3.00000000000000000, -0.125000000000000000, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, -Infinity, Infinity, 0.00000000000000000, 0);
test_pow(-0.500000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_pow(0.500000000000000000, Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(0.500000000000000000, -Infinity, Infinity, 0.00000000000000000, 0);
test_pow(0.500000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_pow(1.50000000000000000, Infinity, Infinity, 0.00000000000000000, 0);
test_pow(1.50000000000000000, -Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(1.50000000000000000, NaN, NaN, 0.00000000000000000, 0);
test_pow(Infinity, NaN, NaN, 0.00000000000000000, 0);
test_pow(Infinity, Infinity, Infinity, 0.00000000000000000, 0);
test_pow(Infinity, -Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(Infinity, 3.00000000000000000, Infinity, 0.00000000000000000, 0);
test_pow(Infinity, 2.00000000000000000, Infinity, 0.00000000000000000, 0);
test_pow(Infinity, 1.00000000000000000, Infinity, 0.00000000000000000, 0);
test_pow(Infinity, 0.500000000000000000, Infinity, 0.00000000000000000, 0);
test_pow(Infinity, -0.500000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(Infinity, -1.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(Infinity, -2.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-Infinity, NaN, NaN, 0.00000000000000000, 0);
test_pow(-Infinity, Infinity, Infinity, 0.00000000000000000, 0);
test_pow(-Infinity, -Infinity, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-Infinity, 3.00000000000000000, -Infinity, 0.00000000000000000, 0);
test_pow(-Infinity, 2.00000000000000000, Infinity, 0.00000000000000000, 0);
test_pow(-Infinity, 1.00000000000000000, -Infinity, 0.00000000000000000, 0);
test_pow(-Infinity, 0.500000000000000000, Infinity, 0.00000000000000000, 0);
test_pow(-Infinity, -0.500000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(-Infinity, -1.00000000000000000, -0.00000000000000000, 0.00000000000000000, 0);
test_pow(-Infinity, -2.00000000000000000, 0.00000000000000000, 0.00000000000000000, 0);
test_pow(NaN, 1.00000000000000000, NaN, 0.00000000000000000, 0);
test_pow(NaN, -1.00000000000000000, NaN, 0.00000000000000000, 0);
test_pow(-2.00000000000000000, 1.00000000000000000, -2.00000000000000000, 0.00000000000000000, 0);
test_pow(-2.00000000000000000, -1.00000000000000000, -0.500000000000000000, 0.00000000000000000, 0);
test_pow(0.0, NaN, NaN, 0.0, 0);
test_pow(0.0, Infinity, 0.0, 0.0, 0);
test_pow(0.0, 3.0, 0.0, 0.0, 0);
test_pow(0.0, 2.0, 0.0, 0.0, 0);
test_pow(0.0, 1.0, 0.0, 0.0, 0);
test_pow(0.0, 0.5, 0.0, 0.0, 0);
test_pow(0.0, 0.0, 1.0, 0.0, 0);
test_pow(0.0, -0.0, 1.0, 0.0, 0);
test_pow(0.0, -0.5, Infinity, 0.0, DIVBYZERO);
test_pow(0.0, -1.0, Infinity, 0.0, DIVBYZERO);
test_pow(0.0, -2.0, Infinity, 0.0, DIVBYZERO);
test_pow(0.0, -3.0, Infinity, 0.0, DIVBYZERO);
test_pow(0.0, -4.0, Infinity, 0.0, DIVBYZERO);
test_pow(0.0, -Infinity, Infinity, 0.0, 0);
test_pow(-0.0, NaN, NaN, 0.0, 0);
test_pow(-0.0, Infinity, 0.0, 0.0, 0);
test_pow(-0.0, 3.0, -0.0, 0.0, 0);
test_pow(-0.0, 2.0, 0.0, 0.0, 0);
test_pow(-0.0, 1.0, -0.0, 0.0, 0);
test_pow(-0.0, 0.5, 0.0, 0.0, 0);
test_pow(-0.0, 0.0, 1.0, 0.0, 0);
test_pow(-0.0, -0.0, 1.0, 0.0, 0);
test_pow(-0.0, -0.5, Infinity, 0.0, DIVBYZERO);
test_pow(-0.0, -1.0, -Infinity, 0.0, DIVBYZERO);
test_pow(-0.0, -2.0, Infinity, 0.0, DIVBYZERO);
test_pow(-0.0, -3.0, -Infinity, 0.0, DIVBYZERO);
test_pow(-0.0, -4.0, Infinity, 0.0, DIVBYZERO);
test_pow(-0.0, -Infinity, Infinity, 0.0, 0);
test_pow(NaN, 0.0, 1.0, 0.0, 0);
test_pow(Infinity, 0.0, 1.0, 0.0, 0);
test_pow(-Infinity, 0.0, 1.0, 0.0, 0);
test_pow(1.0, 0.0, 1.0, 0.0, 0);
test_pow(-1.0, 0.0, 1.0, 0.0, 0);
test_pow(-0.5, 0.0, 1.0, 0.0, 0);
test_pow(NaN, -0.0, 1.0, 0.0, 0);
test_pow(Infinity, -0.0, 1.0, 0.0, 0);
test_pow(-Infinity, -0.0, 1.0, 0.0, 0);
test_pow(1.0, -0.0, 1.0, 0.0, 0);
test_pow(-1.0, -0.0, 1.0, 0.0, 0);
test_pow(-0.5, -0.0, 1.0, 0.0, 0);
test_pow(-1.0, NaN, NaN, 0.0, 0);
test_pow(-1.0, Infinity, 1.0, 0.0, 0);
test_pow(-1.0, -Infinity, 1.0, 0.0, 0);
test_pow(-1.0, 2.0, 1.0, 0.0, 0);
test_pow(-1.0, -1.0, -1.0, 0.0, 0);
test_pow(-1.0, -2.0, 1.0, 0.0, 0);
test_pow(-1.0, -3.0, -1.0, 0.0, 0);
test_pow(-1.0, 0.5, NaN, 0.0, INVALID);
test_pow(1.0, NaN, 1.0, 0.0, 0);
test_pow(1.0, Infinity, 1.0, 0.0, 0);
test_pow(1.0, -Infinity, 1.0, 0.0, 0);
test_pow(1.0, 3.0, 1.0, 0.0, 0);
test_pow(1.0, 0.5, 1.0, 0.0, 0);
test_pow(1.0, -0.5, 1.0, 0.0, 0);
test_pow(1.0, -3.0, 1.0, 0.0, 0);
test_pow(-0.5, 0.5, NaN, 0.0, INVALID);
test_pow(-0.5, 1.5, NaN, 0.0, INVALID);
test_pow(-0.5, 2.0, 0.25, 0.0, 0);
test_pow(-0.5, 3.0, -0.125, 0.0, 0);
test_pow(-0.5, Infinity, 0.0, 0.0, 0);
test_pow(-0.5, -Infinity, Infinity, 0.0, 0);
test_pow(-0.5, NaN, NaN, 0.0, 0);
test_pow(0.5, Infinity, 0.0, 0.0, 0);
test_pow(0.5, -Infinity, Infinity, 0.0, 0);
test_pow(0.5, NaN, NaN, 0.0, 0);
test_pow(1.5, Infinity, Infinity, 0.0, 0);
test_pow(1.5, -Infinity, 0.0, 0.0, 0);
test_pow(1.5, NaN, NaN, 0.0, 0);
test_pow(Infinity, NaN, NaN, 0.0, 0);
test_pow(Infinity, Infinity, Infinity, 0.0, 0);
test_pow(Infinity, -Infinity, 0.0, 0.0, 0);
test_pow(Infinity, 3.0, Infinity, 0.0, 0);
test_pow(Infinity, 2.0, Infinity, 0.0, 0);
test_pow(Infinity, 1.0, Infinity, 0.0, 0);
test_pow(Infinity, 0.5, Infinity, 0.0, 0);
test_pow(Infinity, -0.5, 0.0, 0.0, 0);
test_pow(Infinity, -1.0, 0.0, 0.0, 0);
test_pow(Infinity, -2.0, 0.0, 0.0, 0);
test_pow(-Infinity, NaN, NaN, 0.0, 0);
test_pow(-Infinity, Infinity, Infinity, 0.0, 0);
test_pow(-Infinity, -Infinity, 0.0, 0.0, 0);
test_pow(-Infinity, 3.0, -Infinity, 0.0, 0);
test_pow(-Infinity, 2.0, Infinity, 0.0, 0);
test_pow(-Infinity, 1.0, -Infinity, 0.0, 0);
test_pow(-Infinity, 0.5, Infinity, 0.0, 0);
test_pow(-Infinity, -0.5, 0.0, 0.0, 0);
test_pow(-Infinity, -1.0, -0.0, 0.0, 0);
test_pow(-Infinity, -2.0, 0.0, 0.0, 0);
test_pow(NaN, 1.0, NaN, 0.0, 0);
test_pow(NaN, -1.0, NaN, 0.0, 0);
test_pow(-2.0, 1.0, -2.0, 0.0, 0);
test_pow(-2.0, -1.0, -0.5, 0.0, 0);
// ================================ Mathf.pow ================================
@ -428,106 +428,175 @@ function test_powf(left: f32, right: f32, expected: f32, error: f32, flags: i32)
}
// sanity
test_powf(-8.066848755, 4.535662651, NaN, 0.000000000, INVALID);
test_powf(-8.066848755, 4.535662651, NaN, 0.0, INVALID);
test_powf(4.345239639, -8.887990952, 0.000002134714123, 0.1436440796, INEXACT);
test_powf(-8.381433487, -2.763607264, NaN, 0.000000000, INVALID);
test_powf(-6.531673431, 4.567535400, NaN, 0.000000000, INVALID);
test_powf(-8.381433487, -2.763607264, NaN, 0.0, INVALID);
test_powf(-6.531673431, 4.567535400, NaN, 0.0, INVALID);
test_powf(9.267057419, 4.811392307, 44909.33203, -0.05356409028, INEXACT);
test_powf(-6.450045586, 0.6620717645, NaN, 0.000000000, INVALID);
test_powf(-6.450045586, 0.6620717645, NaN, 0.0, INVALID);
test_powf(7.858890057, 0.05215452611, 1.113517761, 0.1912208945, INEXACT);
test_powf(-0.7920545340, 7.676402569, NaN, 0.000000000, INVALID);
test_powf(-0.7920545340, 7.676402569, NaN, 0.0, INVALID);
test_powf(0.6157026887, 2.011902571, 0.3769077659, 0.3371490538, INEXACT);
test_powf(-0.5587586761, 0.03223983198, NaN, 0.000000000, INVALID);
test_powf(-0.5587586761, 0.03223983198, NaN, 0.0, INVALID);
// special
test_powf(0.000000000, NaN, NaN, 0.000000000, 0);
test_powf(0.000000000, Infinity, 0.000000000, 0.000000000, 0);
test_powf(0.000000000, 3.000000000, 0.000000000, 0.000000000, 0);
test_powf(0.000000000, 2.000000000, 0.000000000, 0.000000000, 0);
test_powf(0.000000000, 1.000000000, 0.000000000, 0.000000000, 0);
test_powf(0.000000000, 0.5000000000, 0.000000000, 0.000000000, 0);
test_powf(0.000000000, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(0.000000000, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(0.000000000, -0.5000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(0.000000000, -1.000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(0.000000000, -2.000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(0.000000000, -3.000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(0.000000000, -4.000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(0.000000000, -Infinity, Infinity, 0.000000000, 0);
test_powf(-0.000000000, NaN, NaN, 0.000000000, 0);
test_powf(-0.000000000, Infinity, 0.000000000, 0.000000000, 0);
test_powf(-0.000000000, 3.000000000, -0.000000000, 0.000000000, 0);
test_powf(-0.000000000, 2.000000000, 0.000000000, 0.000000000, 0);
test_powf(-0.000000000, 1.000000000, -0.000000000, 0.000000000, 0);
test_powf(-0.000000000, 0.5000000000, 0.000000000, 0.000000000, 0);
test_powf(-0.000000000, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-0.000000000, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-0.000000000, -0.5000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(-0.000000000, -1.000000000, -Infinity, 0.000000000, DIVBYZERO);
test_powf(-0.000000000, -2.000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(-0.000000000, -3.000000000, -Infinity, 0.000000000, DIVBYZERO);
test_powf(-0.000000000, -4.000000000, Infinity, 0.000000000, DIVBYZERO);
test_powf(-0.000000000, -Infinity, Infinity, 0.000000000, 0);
test_powf(NaN, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(Infinity, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-Infinity, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-0.5000000000, 0.000000000, 1.000000000, 0.000000000, 0);
test_powf(NaN, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(Infinity, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-Infinity, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-0.5000000000, -0.000000000, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, NaN, NaN, 0.000000000, 0);
test_powf(-1.000000000, Infinity, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, -Infinity, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, 2.000000000, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, -1.000000000, -1.000000000, 0.000000000, 0);
test_powf(-1.000000000, -2.000000000, 1.000000000, 0.000000000, 0);
test_powf(-1.000000000, -3.000000000, -1.000000000, 0.000000000, 0);
test_powf(-1.000000000, 0.5000000000, NaN, 0.000000000, INVALID);
test_powf(1.000000000, NaN, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, Infinity, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, -Infinity, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, 3.000000000, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, 0.5000000000, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, -0.5000000000, 1.000000000, 0.000000000, 0);
test_powf(1.000000000, -3.000000000, 1.000000000, 0.000000000, 0);
test_powf(-0.5000000000, 0.5000000000, NaN, 0.000000000, INVALID);
test_powf(-0.5000000000, 1.500000000, NaN, 0.000000000, INVALID);
test_powf(-0.5000000000, 2.000000000, 0.2500000000, 0.000000000, 0);
test_powf(-0.5000000000, 3.000000000, -0.1250000000, 0.000000000, 0);
test_powf(-0.5000000000, Infinity, 0.000000000, 0.000000000, 0);
test_powf(-0.5000000000, -Infinity, Infinity, 0.000000000, 0);
test_powf(-0.5000000000, NaN, NaN, 0.000000000, 0);
test_powf(0.5000000000, Infinity, 0.000000000, 0.000000000, 0);
test_powf(0.5000000000, -Infinity, Infinity, 0.000000000, 0);
test_powf(0.5000000000, NaN, NaN, 0.000000000, 0);
test_powf(1.500000000, Infinity, Infinity, 0.000000000, 0);
test_powf(1.500000000, -Infinity, 0.000000000, 0.000000000, 0);
test_powf(1.500000000, NaN, NaN, 0.000000000, 0);
test_powf(Infinity, NaN, NaN, 0.000000000, 0);
test_powf(Infinity, Infinity, Infinity, 0.000000000, 0);
test_powf(Infinity, -Infinity, 0.000000000, 0.000000000, 0);
test_powf(Infinity, 3.000000000, Infinity, 0.000000000, 0);
test_powf(Infinity, 2.000000000, Infinity, 0.000000000, 0);
test_powf(Infinity, 1.000000000, Infinity, 0.000000000, 0);
test_powf(Infinity, 0.5000000000, Infinity, 0.000000000, 0);
test_powf(Infinity, -0.5000000000, 0.000000000, 0.000000000, 0);
test_powf(Infinity, -1.000000000, 0.000000000, 0.000000000, 0);
test_powf(Infinity, -2.000000000, 0.000000000, 0.000000000, 0);
test_powf(-Infinity, NaN, NaN, 0.000000000, 0);
test_powf(-Infinity, Infinity, Infinity, 0.000000000, 0);
test_powf(-Infinity, -Infinity, 0.000000000, 0.000000000, 0);
test_powf(-Infinity, 3.000000000, -Infinity, 0.000000000, 0);
test_powf(-Infinity, 2.000000000, Infinity, 0.000000000, 0);
test_powf(-Infinity, 1.000000000, -Infinity, 0.000000000, 0);
test_powf(-Infinity, 0.5000000000, Infinity, 0.000000000, 0);
test_powf(-Infinity, -0.5000000000, 0.000000000, 0.000000000, 0);
test_powf(-Infinity, -1.000000000, -0.000000000, 0.000000000, 0);
test_powf(-Infinity, -2.000000000, 0.000000000, 0.000000000, 0);
test_powf(NaN, 1.000000000, NaN, 0.000000000, 0);
test_powf(NaN, -1.000000000, NaN, 0.000000000, 0);
test_powf(-2.000000000, 1.000000000, -2.000000000, 0.000000000, 0);
test_powf(-2.000000000, -1.000000000, -0.5000000000, 0.000000000, 0);
test_powf(0.0, NaN, NaN, 0.0, 0);
test_powf(0.0, Infinity, 0.0, 0.0, 0);
test_powf(0.0, 3.0, 0.0, 0.0, 0);
test_powf(0.0, 2.0, 0.0, 0.0, 0);
test_powf(0.0, 1.0, 0.0, 0.0, 0);
test_powf(0.0, 0.5, 0.0, 0.0, 0);
test_powf(0.0, 0.0, 1.0, 0.0, 0);
test_powf(0.0, -0.0, 1.0, 0.0, 0);
test_powf(0.0, -0.5, Infinity, 0.0, DIVBYZERO);
test_powf(0.0, -1.0, Infinity, 0.0, DIVBYZERO);
test_powf(0.0, -2.0, Infinity, 0.0, DIVBYZERO);
test_powf(0.0, -3.0, Infinity, 0.0, DIVBYZERO);
test_powf(0.0, -4.0, Infinity, 0.0, DIVBYZERO);
test_powf(0.0, -Infinity, Infinity, 0.0, 0);
test_powf(-0.0, NaN, NaN, 0.0, 0);
test_powf(-0.0, Infinity, 0.0, 0.0, 0);
test_powf(-0.0, 3.0, -0.0, 0.0, 0);
test_powf(-0.0, 2.0, 0.0, 0.0, 0);
test_powf(-0.0, 1.0, -0.0, 0.0, 0);
test_powf(-0.0, 0.5, 0.0, 0.0, 0);
test_powf(-0.0, 0.0, 1.0, 0.0, 0);
test_powf(-0.0, -0.0, 1.0, 0.0, 0);
test_powf(-0.0, -0.5, Infinity, 0.0, DIVBYZERO);
test_powf(-0.0, -1.0, -Infinity, 0.0, DIVBYZERO);
test_powf(-0.0, -2.0, Infinity, 0.0, DIVBYZERO);
test_powf(-0.0, -3.0, -Infinity, 0.0, DIVBYZERO);
test_powf(-0.0, -4.0, Infinity, 0.0, DIVBYZERO);
test_powf(-0.0, -Infinity, Infinity, 0.0, 0);
test_powf(NaN, 0.0, 1.0, 0.0, 0);
test_powf(Infinity, 0.0, 1.0, 0.0, 0);
test_powf(-Infinity, 0.0, 1.0, 0.0, 0);
test_powf(1.0, 0.0, 1.0, 0.0, 0);
test_powf(-1.0, 0.0, 1.0, 0.0, 0);
test_powf(-0.5, 0.0, 1.0, 0.0, 0);
test_powf(NaN, -0.0, 1.0, 0.0, 0);
test_powf(Infinity, -0.0, 1.0, 0.0, 0);
test_powf(-Infinity, -0.0, 1.0, 0.0, 0);
test_powf(1.0, -0.0, 1.0, 0.0, 0);
test_powf(-1.0, -0.0, 1.0, 0.0, 0);
test_powf(-0.5, -0.0, 1.0, 0.0, 0);
test_powf(-1.0, NaN, NaN, 0.0, 0);
test_powf(-1.0, Infinity, 1.0, 0.0, 0);
test_powf(-1.0, -Infinity, 1.0, 0.0, 0);
test_powf(-1.0, 2.0, 1.0, 0.0, 0);
test_powf(-1.0, -1.0, -1.0, 0.0, 0);
test_powf(-1.0, -2.0, 1.0, 0.0, 0);
test_powf(-1.0, -3.0, -1.0, 0.0, 0);
test_powf(-1.0, 0.5, NaN, 0.0, INVALID);
test_powf(1.0, NaN, 1.0, 0.0, 0);
test_powf(1.0, Infinity, 1.0, 0.0, 0);
test_powf(1.0, -Infinity, 1.0, 0.0, 0);
test_powf(1.0, 3.0, 1.0, 0.0, 0);
test_powf(1.0, 0.5, 1.0, 0.0, 0);
test_powf(1.0, -0.5, 1.0, 0.0, 0);
test_powf(1.0, -3.0, 1.0, 0.0, 0);
test_powf(-0.5, 0.5, NaN, 0.0, INVALID);
test_powf(-0.5, 1.5, NaN, 0.0, INVALID);
test_powf(-0.5, 2.0, 0.25, 0.0, 0);
test_powf(-0.5, 3.0, -0.125, 0.0, 0);
test_powf(-0.5, Infinity, 0.0, 0.0, 0);
test_powf(-0.5, -Infinity, Infinity, 0.0, 0);
test_powf(-0.5, NaN, NaN, 0.0, 0);
test_powf(0.5, Infinity, 0.0, 0.0, 0);
test_powf(0.5, -Infinity, Infinity, 0.0, 0);
test_powf(0.5, NaN, NaN, 0.0, 0);
test_powf(1.5, Infinity, Infinity, 0.0, 0);
test_powf(1.5, -Infinity, 0.0, 0.0, 0);
test_powf(1.5, NaN, NaN, 0.0, 0);
test_powf(Infinity, NaN, NaN, 0.0, 0);
test_powf(Infinity, Infinity, Infinity, 0.0, 0);
test_powf(Infinity, -Infinity, 0.0, 0.0, 0);
test_powf(Infinity, 3.0, Infinity, 0.0, 0);
test_powf(Infinity, 2.0, Infinity, 0.0, 0);
test_powf(Infinity, 1.0, Infinity, 0.0, 0);
test_powf(Infinity, 0.5, Infinity, 0.0, 0);
test_powf(Infinity, -0.5, 0.0, 0.0, 0);
test_powf(Infinity, -1.0, 0.0, 0.0, 0);
test_powf(Infinity, -2.0, 0.0, 0.0, 0);
test_powf(-Infinity, NaN, NaN, 0.0, 0);
test_powf(-Infinity, Infinity, Infinity, 0.0, 0);
test_powf(-Infinity, -Infinity, 0.0, 0.0, 0);
test_powf(-Infinity, 3.0, -Infinity, 0.0, 0);
test_powf(-Infinity, 2.0, Infinity, 0.0, 0);
test_powf(-Infinity, 1.0, -Infinity, 0.0, 0);
test_powf(-Infinity, 0.5, Infinity, 0.0, 0);
test_powf(-Infinity, -0.5, 0.0, 0.0, 0);
test_powf(-Infinity, -1.0, -0.0, 0.0, 0);
test_powf(-Infinity, -2.0, 0.0, 0.0, 0);
test_powf(NaN, 1.0, NaN, 0.0, 0);
test_powf(NaN, -1.0, NaN, 0.0, 0);
test_powf(-2.0, 1.0, -2.0, 0.0, 0);
test_powf(-2.0, -1.0, -0.5, 0.0, 0);
// ================================ Math.cbrt ================================
function test_cbrt(value: f64, expected: f64, error: f64, flags: i32): void {
check<f64>(NativeMath.cbrt(value), expected, error, flags);
check<f64>(JSMath.cbrt(value), expected, error, flags);
}
// sanity
test_cbrt(-8.06684839057968084, -2.00555525450202454, 0.466679513454437256, INEXACT);
test_cbrt(4.34523984933830487, 1.63181624105156353, -0.0816027149558067322, INEXACT);
test_cbrt(-8.38143342755524934, -2.03129391067336096, -0.0481018163263797760, INEXACT);
test_cbrt(-6.53167358191348413, -1.86928200122049248, 0.0862401872873306274, INEXACT);
test_cbrt(9.26705696697258574, 2.10045772085970217, -0.272298902273178101, INEXACT);
test_cbrt(0.661985898099504477, 0.871531147045597310, 0.441491812467575073, INEXACT);
test_cbrt(-0.406603922385355310, -0.740839030300223023, 0.0164538137614727020, INEXACT);
test_cbrt(0.561759746220724110, 0.825119540055928580, 0.306806385517120361, INEXACT);
test_cbrt(0.774152296591303690, 0.918210247895991372, 0.0654399842023849487, INEXACT);
test_cbrt(-0.678763702639402444, -0.878832690658009397, -0.201671317219734192, INEXACT);
// special
test_cbrt(NaN, NaN, 0.0, 0);
test_cbrt(Infinity, Infinity, 0.0, 0);
test_cbrt(-Infinity, -Infinity, 0.0, 0);
test_cbrt(0.0, 0.0, 0.0, 0);
test_cbrt(-0.0, -0.0, 0.0, 0);
test_cbrt(9.31322574615478516e-10, 0.0009765625, 0.0, 0);
test_cbrt(-9.31322574615478516e-10, -0.0009765625, 0.0, 0);
test_cbrt(1.0, 1.0, 0.0, 0);
test_cbrt(-1.0, -1.0, 0.0, 0);
test_cbrt(8.0, 2.0, 0.0, 0);
// ================================ Mathf.cbrt ================================
function test_cbrtf(value: f32, expected: f32, error: f32, flags: i32): void {
check<f32>(NativeMathf.cbrt(value), expected, error, flags);
}
// sanity
test_cbrtf(-8.066848755, -2.005555391, -0.4471924007, INEXACT);
test_cbrtf(4.345239639, 1.631816268, 0.4463625252, INEXACT);
test_cbrtf(-8.381433487, -2.031293869, 0.1948342621, INEXACT);
test_cbrtf(-6.531673431, -1.869282007, -0.1707551479, INEXACT);
test_cbrtf(9.267057419, 2.100457668, -0.3636204302, INEXACT);
test_cbrtf(0.6619858742, 0.8715311289, -0.1285720915, INEXACT);
test_cbrtf(-0.4066039324, -0.7408390641, -0.4655757546, INEXACT);
test_cbrtf(0.5617597699, 0.8251195550, 0.05601907894, INEXACT);
test_cbrtf(0.7741522789, 0.9182102680, 0.4549820423, INEXACT);
test_cbrtf(-0.6787636876, -0.8788326979, -0.2297896743, INEXACT);
// special
test_cbrtf(NaN, NaN, 0.0, 0);
test_cbrtf(Infinity, Infinity, 0.0, 0);
test_cbrtf(-Infinity, -Infinity, 0.0, 0);
test_cbrtf(0.0, 0.0, 0.0, 0);
test_cbrtf(-0.0, -0.0, 0.0, 0);
test_cbrtf(9.313225746e-10, 0.0009765625, 0.0, 0);
test_cbrtf(-9.313225746e-10, -0.0009765625, 0.0, 0);
test_cbrtf(1.0, 1.0, 0.0, 0);
test_cbrtf(-1.0, -1.0, 0.0, 0);
test_cbrtf(8.0, 2.0, 0.0, 0);
// ================================ Mathf.random ================================
NativeMath.seedRandom(reinterpret<u64>(JSMath.random()));
for (let i = 0; i < 1e7; ++i) {
let r = NativeMath.random();
assert(r >= 0.0 && r < 1.0);
}

File diff suppressed because it is too large Load Diff