aboutsummaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-05-29 18:27:43 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-05-29 18:27:43 +0200
commitd7dba495fd5703facfb8e4339da161da895dab35 (patch)
treec72d9a5cc06743dd606d8252b54975714fd5d9a3 /core/math
parentc05f6b4a31666af0bfb346398b8e7420033a6a4b (diff)
Last of the Endian float in math.odin.
Diffstat (limited to 'core/math')
-rw-r--r--core/math/math.odin186
1 files changed, 111 insertions, 75 deletions
diff --git a/core/math/math.odin b/core/math/math.odin
index c2a08ca09..1239d3e61 100644
--- a/core/math/math.odin
+++ b/core/math/math.odin
@@ -934,7 +934,7 @@ factorial :: proc(n: int) -> int {
return table[n];
}
-classify_f16 :: proc(x: f16) -> Float_Class {
+classify_f16 :: proc(x: f16) -> Float_Class {
switch {
case x == 0:
i := transmute(i16)x;
@@ -958,7 +958,9 @@ classify_f16 :: proc(x: f16) -> Float_Class {
}
return .Normal;
}
-classify_f32 :: proc(x: f32) -> Float_Class {
+classify_f16le :: proc(x: f16le) -> Float_Class { return #force_inline classify_f16(f16(x)); }
+classify_f16be :: proc(x: f16be) -> Float_Class { return #force_inline classify_f16(f16(x)); }
+classify_f32 :: proc(x: f32) -> Float_Class {
switch {
case x == 0:
i := transmute(i32)x;
@@ -982,7 +984,9 @@ classify_f32 :: proc(x: f32) -> Float_Class {
}
return .Normal;
}
-classify_f64 :: proc(x: f64) -> Float_Class {
+classify_f32le :: proc(x: f32le) -> Float_Class { return #force_inline classify_f32(f32(x)); }
+classify_f32be :: proc(x: f32be) -> Float_Class { return #force_inline classify_f32(f32(x)); }
+classify_f64 :: proc(x: f64) -> Float_Class {
switch {
case x == 0:
i := transmute(i64)x;
@@ -1005,13 +1009,28 @@ classify_f64 :: proc(x: f64) -> Float_Class {
}
return .Normal;
}
-classify :: proc{classify_f16, classify_f32, classify_f64};
-
-is_nan_f16 :: proc(x: f16) -> bool { return classify(x) == .NaN; }
-is_nan_f32 :: proc(x: f32) -> bool { return classify(x) == .NaN; }
-is_nan_f64 :: proc(x: f64) -> bool { return classify(x) == .NaN; }
-is_nan :: proc{is_nan_f16, is_nan_f32, is_nan_f64};
+classify_f64le :: proc(x: f64le) -> Float_Class { return #force_inline classify_f64(f64(x)); }
+classify_f64be :: proc(x: f64be) -> Float_Class { return #force_inline classify_f64(f64(x)); }
+classify :: proc{
+ classify_f16, classify_f16le, classify_f16be,
+ classify_f32, classify_f32le, classify_f32be,
+ classify_f64, classify_f64le, classify_f64be,
+};
+is_nan_f16 :: proc(x: f16) -> bool { return classify(x) == .NaN; }
+is_nan_f16le :: proc(x: f16le) -> bool { return classify(x) == .NaN; }
+is_nan_f16be :: proc(x: f16be) -> bool { return classify(x) == .NaN; }
+is_nan_f32 :: proc(x: f32) -> bool { return classify(x) == .NaN; }
+is_nan_f32le :: proc(x: f32le) -> bool { return classify(x) == .NaN; }
+is_nan_f32be :: proc(x: f32be) -> bool { return classify(x) == .NaN; }
+is_nan_f64 :: proc(x: f64) -> bool { return classify(x) == .NaN; }
+is_nan_f64le :: proc(x: f64le) -> bool { return classify(x) == .NaN; }
+is_nan_f64be :: proc(x: f64be) -> bool { return classify(x) == .NaN; }
+is_nan :: proc{
+ is_nan_f16, is_nan_f16le, is_nan_f16be,
+ is_nan_f32, is_nan_f32le, is_nan_f32be,
+ is_nan_f64, is_nan_f64le, is_nan_f64be,
+};
// is_inf reports whether f is an infinity, according to sign.
// If sign > 0, is_inf reports whether f is positive infinity.
@@ -1073,13 +1092,25 @@ is_inf :: proc{
is_inf_f64, is_inf_f64le, is_inf_f64be,
};
-inf_f16 :: proc(sign: int) -> f16 {
- return f16(inf_f16(sign));
+inf_f16 :: proc(sign: int) -> f16 {
+ return f16(inf_f64(sign));
+}
+inf_f16le :: proc(sign: int) -> f16le {
+ return f16le(inf_f64(sign));
}
-inf_f32 :: proc(sign: int) -> f32 {
+inf_f16be :: proc(sign: int) -> f16be {
+ return f16be(inf_f64(sign));
+}
+inf_f32 :: proc(sign: int) -> f32 {
return f32(inf_f64(sign));
}
-inf_f64 :: proc(sign: int) -> f64 {
+inf_f32le :: proc(sign: int) -> f32le {
+ return f32le(inf_f64(sign));
+}
+inf_f32be :: proc(sign: int) -> f32be {
+ return f32be(inf_f64(sign));
+}
+inf_f64 :: proc(sign: int) -> f64 {
v: u64;
if sign >= 0 {
v = 0x7ff00000_00000000;
@@ -1088,17 +1119,41 @@ inf_f64 :: proc(sign: int) -> f64 {
}
return transmute(f64)v;
}
+inf_f64le :: proc(sign: int) -> f64le {
+ return f64le(inf_f64(sign));
+}
+inf_f64be :: proc(sign: int) -> f64be {
+ return f64be(inf_f64(sign));
+}
-nan_f16 :: proc() -> f16 {
+nan_f16 :: proc() -> f16 {
return f16(nan_f64());
}
-nan_f32 :: proc() -> f32 {
+nan_f16le :: proc() -> f16le {
+ return f16le(nan_f64());
+}
+nan_f16be :: proc() -> f16be {
+ return f16be(nan_f64());
+}
+nan_f32 :: proc() -> f32 {
return f32(nan_f64());
}
-nan_f64 :: proc() -> f64 {
+nan_f32le :: proc() -> f32le {
+ return f32le(nan_f64());
+}
+nan_f32be :: proc() -> f32be {
+ return f32be(nan_f64());
+}
+nan_f64 :: proc() -> f64 {
v: u64 = 0x7ff80000_00000001;
return transmute(f64)v;
}
+nan_f64le :: proc() -> f64le {
+ return f64le(nan_f64());
+}
+nan_f64be :: proc() -> f64be {
+ return f64be(nan_f64());
+}
is_power_of_two :: proc(x: int) -> bool {
return x > 0 && (x & (x-1)) == 0;
@@ -1155,14 +1210,30 @@ cumsum :: proc(dst, src: $T/[]$E) -> T
}
-atan2_f16 :: proc(y, x: f16) -> f16 {
+atan2_f16 :: proc(y, x: f16) -> f16 {
// TODO(bill): Better atan2_f16
return f16(atan2_f64(f64(y), f64(x)));
}
-atan2_f32 :: proc(y, x: f32) -> f32 {
+atan2_f16le :: proc(y, x: f16le) -> f16le {
+ // TODO(bill): Better atan2_f16
+ return f16le(atan2_f64(f64(y), f64(x)));
+}
+atan2_f16be :: proc(y, x: f16be) -> f16be {
+ // TODO(bill): Better atan2_f16
+ return f16be(atan2_f64(f64(y), f64(x)));
+}
+atan2_f32 :: proc(y, x: f32) -> f32 {
// TODO(bill): Better atan2_f32
return f32(atan2_f64(f64(y), f64(x)));
}
+atan2_f32le :: proc(y, x: f32le) -> f32le {
+ // TODO(bill): Better atan2_f32
+ return f32le(atan2_f64(f64(y), f64(x)));
+}
+atan2_f32be :: proc(y, x: f32be) -> f32be {
+ // TODO(bill): Better atan2_f32
+ return f32be(atan2_f64(f64(y), f64(x)));
+}
atan2_f64 :: proc(y, x: f64) -> f64 {
// TODO(bill): Faster atan2_f64 if possible
@@ -1249,80 +1320,45 @@ atan2_f64 :: proc(y, x: f64) -> f64 {
}
return q;
}
-
-
-atan2 :: proc{atan2_f16, atan2_f32, atan2_f64};
-
-atan_f16 :: proc(x: f16) -> f16 {
- return atan2_f16(x, 1);
-}
-atan_f32 :: proc(x: f32) -> f32 {
- return atan2_f32(x, 1);
+atan2_f64le :: proc(y, x: f64le) -> f64le {
+ // TODO(bill): Better atan2_f32
+ return f64le(atan2_f64(f64(y), f64(x)));
}
-atan_f64 :: proc(x: f64) -> f64 {
- return atan2_f64(x, 1);
+atan2_f64be :: proc(y, x: f64be) -> f64be {
+ // TODO(bill): Better atan2_f32
+ return f64be(atan2_f64(f64(y), f64(x)));
}
-atan :: proc{atan_f16, atan_f32, atan_f64};
-asin_f16 :: proc(x: f16) -> f16 {
- return atan2_f16(x, 1 + sqrt_f16(1 - x*x));
-}
-asin_f32 :: proc(x: f32) -> f32 {
- return atan2_f32(x, 1 + sqrt_f32(1 - x*x));
-}
-asin_f64 :: proc(x: f64) -> f64 {
- return atan2_f64(x, 1 + sqrt_f64(1 - x*x));
-}
-asin :: proc{asin_f16, asin_f32, asin_f64};
+atan2 :: proc{
+ atan2_f16, atan2_f16le, atan2_f16be,
+ atan2_f32, atan2_f32le, atan2_f32be,
+ atan2_f64, atan2_f64le, atan2_f64be,
+};
-acos_f16 :: proc(x: f16) -> f16 {
- return 2 * atan2_f16(sqrt_f16(1 - x), sqrt_f16(1 + x));
+atan :: proc(x: $T) -> T where intrinsics.type_is_float(x) {
+ return atan2(x, 1);
}
-acos_f32 :: proc(x: f32) -> f32 {
- return 2 * atan2_f32(sqrt_f32(1 - x), sqrt_f32(1 + x));
-}
-acos_f64 :: proc(x: f64) -> f64 {
- return 2 * atan2_f64(sqrt_f64(1 - x), sqrt_f64(1 + x));
-}
-acos :: proc{acos_f16, acos_f32, acos_f64};
-
-sinh_f16 :: proc(x: f16) -> f16 {
- return (exp(x) - exp(-x))*0.5;
+asin :: proc(x: $T) -> T where intrinsics.type_is_float(x) {
+ return atan2(x, 1 + sqrt(1 - x*x));
}
-sinh_f32 :: proc(x: f32) -> f32 {
- return (exp(x) - exp(-x))*0.5;
+
+acos :: proc(x: $T) -> T where intrinsics.type_is_float(x) {
+ return 2 * atan2(sqrt(1 - x), sqrt(1 + x));
}
-sinh_f64 :: proc(x: f64) -> f64 {
+
+sinh :: proc(x: $T) -> T where intrinsics.type_is_float(x) {
return (exp(x) - exp(-x))*0.5;
}
-sinh :: proc{sinh_f16, sinh_f32, sinh_f64};
-cosh_f16 :: proc(x: f16) -> f16 {
- return (exp(x) + exp(-x))*0.5;
-}
-cosh_f32 :: proc(x: f32) -> f32 {
+cosh :: proc(x: $T) -> T where intrinsics.type_is_float(x) {
return (exp(x) + exp(-x))*0.5;
}
-cosh_f64 :: proc(x: f64) -> f64 {
- return (exp(x) + exp(-x))*0.5;
-}
-cosh :: proc{cosh_f16, cosh_f32, cosh_f64};
-tanh_f16 :: proc(x: f16) -> f16 {
- t := exp(2*x);
- return (t - 1) / (t + 1);
-}
-tanh_f32 :: proc(x: f32) -> f32 {
- t := exp(2*x);
- return (t - 1) / (t + 1);
-}
-tanh_f64 :: proc(x: f64) -> f64 {
+tanh :: proc(x: $T) -> T where intrinsics.type_is_float(x) {
t := exp(2*x);
return (t - 1) / (t + 1);
}
-tanh :: proc{tanh_f16, tanh_f32, tanh_f64};
-
F16_DIG :: 3;
F16_EPSILON :: 0.00097656;