Browse Source

Last of the Endian float in math.odin.

Jeroen van Rijn 4 years ago
parent
commit
d7dba495fd
1 changed files with 111 additions and 75 deletions
  1. 111 75
      core/math/math.odin

+ 111 - 75
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;