diff options
| author | gingerBill <bill@gingerbill.org> | 2022-11-29 11:39:44 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-11-29 11:39:44 +0000 |
| commit | 0c25f7cdc5bdf34d7b0941785579eea2d50a279c (patch) | |
| tree | 9d77b611c016c0d09b14e6bf8b3cf335c507724f /core/math | |
| parent | e5c243ee930828c7277bdc5ef9d18432f3bc3849 (diff) | |
Improve core:math procedures and add loads of unit tests
Diffstat (limited to 'core/math')
| -rw-r--r-- | core/math/math.odin | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/core/math/math.odin b/core/math/math.odin index 027a9c8cd..ce58a0111 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -1088,7 +1088,7 @@ is_nan :: proc{ // If sign < 0, is_inf reports whether f is negative infinity. // If sign == 0, is_inf reports whether f is either infinity. is_inf_f16 :: proc "contextless" (x: f16, sign: int = 0) -> bool { - class := classify(abs(x)) + class := classify(x) switch { case sign > 0: return class == .Inf @@ -1105,7 +1105,7 @@ is_inf_f16be :: proc "contextless" (x: f16be, sign: int = 0) -> bool { } is_inf_f32 :: proc "contextless" (x: f32, sign: int = 0) -> bool { - class := classify(abs(x)) + class := classify(x) switch { case sign > 0: return class == .Inf @@ -1122,7 +1122,7 @@ is_inf_f32be :: proc "contextless" (x: f32be, sign: int = 0) -> bool { } is_inf_f64 :: proc "contextless" (x: f64, sign: int = 0) -> bool { - class := classify(abs(x)) + class := classify(x) switch { case sign > 0: return class == .Inf @@ -1344,20 +1344,20 @@ atan2_f64 :: proc "contextless" (y, x: f64) -> f64 { } return copy_sign(PI, y) case x == 0: - return copy_sign(PI*0.5, y) + return copy_sign(PI/2, y) case is_inf(x, 0): if is_inf(x, 1) { if is_inf(y, 0) { - return copy_sign(PI*0.25, y) + return copy_sign(PI/4, y) } return copy_sign(0, y) } if is_inf(y, 0) { - return copy_sign(PI*0.75, y) + return copy_sign(3*PI/4, y) } return copy_sign(PI, y) case is_inf(y, 0): - return copy_sign(PI*0.5, y) + return copy_sign(PI/2, y) } q := atan(y / x) @@ -1599,16 +1599,46 @@ acos :: proc{ } sinh :: proc "contextless" (x: $T) -> T where intrinsics.type_is_float(T) { - return (exp(x) - exp(-x))*0.5 + return copy_sign(((exp(x) - exp(-x))*0.5), x) } cosh :: proc "contextless" (x: $T) -> T where intrinsics.type_is_float(T) { - return (exp(x) + exp(-x))*0.5 + return ((exp(x) + exp(-x))*0.5) } -tanh :: proc "contextless" (x: $T) -> T where intrinsics.type_is_float(T) { - t := exp(2*x) - return (t - 1) / (t + 1) +tanh :: proc "contextless" (y: $T) -> T where intrinsics.type_is_float(T) { + P0 :: -9.64399179425052238628e-1 + P1 :: -9.92877231001918586564e1 + P2 :: -1.61468768441708447952e3 + Q0 :: +1.12811678491632931402e2 + Q1 :: +2.23548839060100448583e3 + Q2 :: +4.84406305325125486048e3 + + MAXLOG :: 8.8029691931113054295988e+01 // log(2**127) + + + x := f64(y) + z := abs(x) + switch { + case z > 0.5*MAXLOG: + if x < 0 { + return -1 + } + return 1 + case z >= 0.625: + s := exp(2 * z) + z = 1 - 2/(s+1) + if x < 0 { + z = -z + } + case: + if x == 0 { + return T(x) + } + s := x * x + z = x + x*s*((P0*s+P1)*s+P2)/(((s+Q0)*s+Q1)*s+Q2) + } + return T(z) } asinh :: proc "contextless" (y: $T) -> T where intrinsics.type_is_float(T) { |