Commit cf007e37b9

Marc Tiehuis <marctiehuis@gmail.com>
2019-02-13 11:27:23
Add f128 support for fabs, isinf, isnan, inf and nan functions
1 parent be861a8
std/math/fabs.zig
@@ -14,6 +14,7 @@ pub fn fabs(x: var) @typeOf(x) {
         f16 => fabs16(x),
         f32 => fabs32(x),
         f64 => fabs64(x),
+        f128 => fabs128(x),
         else => @compileError("fabs not implemented for " ++ @typeName(T)),
     };
 }
@@ -36,10 +37,17 @@ fn fabs64(x: f64) f64 {
     return @bitCast(f64, u);
 }
 
+fn fabs128(x: f128) f128 {
+    var u = @bitCast(u128, x);
+    u &= maxInt(u128) >> 1;
+    return @bitCast(f128, u);
+}
+
 test "math.fabs" {
     expect(fabs(f16(1.0)) == fabs16(1.0));
     expect(fabs(f32(1.0)) == fabs32(1.0));
     expect(fabs(f64(1.0)) == fabs64(1.0));
+    expect(fabs(f128(1.0)) == fabs128(1.0));
 }
 
 test "math.fabs16" {
@@ -57,6 +65,11 @@ test "math.fabs64" {
     expect(fabs64(-1.0) == 1.0);
 }
 
+test "math.fabs128" {
+    expect(fabs128(1.0) == 1.0);
+    expect(fabs128(-1.0) == 1.0);
+}
+
 test "math.fabs16.special" {
     expect(math.isPositiveInf(fabs(math.inf(f16))));
     expect(math.isPositiveInf(fabs(-math.inf(f16))));
@@ -74,3 +87,9 @@ test "math.fabs64.special" {
     expect(math.isPositiveInf(fabs(-math.inf(f64))));
     expect(math.isNan(fabs(math.nan(f64))));
 }
+
+test "math.fabs128.special" {
+    expect(math.isPositiveInf(fabs(math.inf(f128))));
+    expect(math.isPositiveInf(fabs(-math.inf(f128))));
+    expect(math.isNan(fabs(math.nan(f128))));
+}
std/math/index.zig
@@ -51,6 +51,12 @@ pub const nan_f64 = @bitCast(f64, nan_u64);
 pub const inf_u64 = u64(0x7FF << 52);
 pub const inf_f64 = @bitCast(f64, inf_u64);
 
+pub const nan_u128 = u128(0x7fff0000000000000000000000000001);
+pub const nan_f128 = @bitCast(f128, nan_u128);
+
+pub const inf_u128 = u128(0x7fff0000000000000000000000000000);
+pub const inf_f128 = @bitCast(f128, inf_u128);
+
 pub const nan = @import("nan.zig").nan;
 pub const snan = @import("nan.zig").snan;
 pub const inf = @import("inf.zig").inf;
@@ -379,7 +385,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
         return u0;
     }
     const is_signed = from < 0;
-    const largest_positive_integer = max(if (from<0) (-from)-1 else from, to); // two's complement
+    const largest_positive_integer = max(if (from < 0) (-from) - 1 else from, to); // two's complement
     const base = log2(largest_positive_integer);
     const upper = (1 << base) - 1;
     var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
@@ -752,6 +758,7 @@ test "minInt and maxInt" {
     testing.expect(maxInt(u16) == 65535);
     testing.expect(maxInt(u32) == 4294967295);
     testing.expect(maxInt(u64) == 18446744073709551615);
+    testing.expect(maxInt(u128) == 340282366920938463463374607431768211455);
 
     testing.expect(maxInt(i0) == 0);
     testing.expect(maxInt(i1) == 0);
@@ -760,6 +767,7 @@ test "minInt and maxInt" {
     testing.expect(maxInt(i32) == 2147483647);
     testing.expect(maxInt(i63) == 4611686018427387903);
     testing.expect(maxInt(i64) == 9223372036854775807);
+    testing.expect(maxInt(i128) == 170141183460469231731687303715884105727);
 
     testing.expect(minInt(u0) == 0);
     testing.expect(minInt(u1) == 0);
@@ -768,6 +776,7 @@ test "minInt and maxInt" {
     testing.expect(minInt(u32) == 0);
     testing.expect(minInt(u63) == 0);
     testing.expect(minInt(u64) == 0);
+    testing.expect(minInt(u128) == 0);
 
     testing.expect(minInt(i0) == 0);
     testing.expect(minInt(i1) == -1);
@@ -776,6 +785,7 @@ test "minInt and maxInt" {
     testing.expect(minInt(i32) == -2147483648);
     testing.expect(minInt(i63) == -4611686018427387904);
     testing.expect(minInt(i64) == -9223372036854775808);
+    testing.expect(minInt(i128) == -170141183460469231731687303715884105728);
 }
 
 test "max value type" {
std/math/inf.zig
@@ -3,9 +3,10 @@ const math = std.math;
 
 pub fn inf(comptime T: type) T {
     return switch (T) {
-        f16 => @bitCast(f16, math.inf_u16),
-        f32 => @bitCast(f32, math.inf_u32),
-        f64 => @bitCast(f64, math.inf_u64),
+        f16 => math.inf_f16,
+        f32 => math.inf_f32,
+        f64 => math.inf_f64,
+        f128 => math.inf_f128,
         else => @compileError("inf not implemented for " ++ @typeName(T)),
     };
 }
std/math/isinf.zig
@@ -18,6 +18,10 @@ pub fn isInf(x: var) bool {
             const bits = @bitCast(u64, x);
             return bits & (maxInt(u64) >> 1) == (0x7FF << 52);
         },
+        f128 => {
+            const bits = @bitCast(u128, x);
+            return bits & (maxInt(u128) >> 1) == (0x7FFF << 112);
+        },
         else => {
             @compileError("isInf not implemented for " ++ @typeName(T));
         },
@@ -36,6 +40,9 @@ pub fn isPositiveInf(x: var) bool {
         f64 => {
             return @bitCast(u64, x) == 0x7FF << 52;
         },
+        f128 => {
+            return @bitCast(u128, x) == 0x7FFF << 112;
+        },
         else => {
             @compileError("isPositiveInf not implemented for " ++ @typeName(T));
         },
@@ -54,6 +61,9 @@ pub fn isNegativeInf(x: var) bool {
         f64 => {
             return @bitCast(u64, x) == 0xFFF << 52;
         },
+        f128 => {
+            return @bitCast(u128, x) == 0xFFFF << 112;
+        },
         else => {
             @compileError("isNegativeInf not implemented for " ++ @typeName(T));
         },
@@ -67,12 +77,16 @@ test "math.isInf" {
     expect(!isInf(f32(-0.0)));
     expect(!isInf(f64(0.0)));
     expect(!isInf(f64(-0.0)));
+    expect(!isInf(f128(0.0)));
+    expect(!isInf(f128(-0.0)));
     expect(isInf(math.inf(f16)));
     expect(isInf(-math.inf(f16)));
     expect(isInf(math.inf(f32)));
     expect(isInf(-math.inf(f32)));
     expect(isInf(math.inf(f64)));
     expect(isInf(-math.inf(f64)));
+    expect(isInf(math.inf(f128)));
+    expect(isInf(-math.inf(f128)));
 }
 
 test "math.isPositiveInf" {
@@ -82,12 +96,16 @@ test "math.isPositiveInf" {
     expect(!isPositiveInf(f32(-0.0)));
     expect(!isPositiveInf(f64(0.0)));
     expect(!isPositiveInf(f64(-0.0)));
+    expect(!isPositiveInf(f128(0.0)));
+    expect(!isPositiveInf(f128(-0.0)));
     expect(isPositiveInf(math.inf(f16)));
     expect(!isPositiveInf(-math.inf(f16)));
     expect(isPositiveInf(math.inf(f32)));
     expect(!isPositiveInf(-math.inf(f32)));
     expect(isPositiveInf(math.inf(f64)));
     expect(!isPositiveInf(-math.inf(f64)));
+    expect(isPositiveInf(math.inf(f128)));
+    expect(!isPositiveInf(-math.inf(f128)));
 }
 
 test "math.isNegativeInf" {
@@ -97,10 +115,14 @@ test "math.isNegativeInf" {
     expect(!isNegativeInf(f32(-0.0)));
     expect(!isNegativeInf(f64(0.0)));
     expect(!isNegativeInf(f64(-0.0)));
+    expect(!isNegativeInf(f128(0.0)));
+    expect(!isNegativeInf(f128(-0.0)));
     expect(!isNegativeInf(math.inf(f16)));
     expect(isNegativeInf(-math.inf(f16)));
     expect(!isNegativeInf(math.inf(f32)));
     expect(isNegativeInf(-math.inf(f32)));
     expect(!isNegativeInf(math.inf(f64)));
     expect(isNegativeInf(-math.inf(f64)));
+    expect(!isNegativeInf(math.inf(f128)));
+    expect(isNegativeInf(-math.inf(f128)));
 }
std/math/isnan.zig
@@ -18,6 +18,10 @@ pub fn isNan(x: var) bool {
             const bits = @bitCast(u64, x);
             return (bits & (maxInt(u64) >> 1)) > (u64(0x7FF) << 52);
         },
+        f128 => {
+            const bits = @bitCast(u128, x);
+            return (bits & (maxInt(u128) >> 1)) > (u128(0x7FFF) << 112);
+        },
         else => {
             @compileError("isNan not implemented for " ++ @typeName(T));
         },
@@ -34,7 +38,9 @@ test "math.isNan" {
     expect(isNan(math.nan(f16)));
     expect(isNan(math.nan(f32)));
     expect(isNan(math.nan(f64)));
+    expect(isNan(math.nan(f128)));
     expect(!isNan(f16(1.0)));
     expect(!isNan(f32(1.0)));
     expect(!isNan(f64(1.0)));
+    expect(!isNan(f128(1.0)));
 }
std/math/nan.zig
@@ -2,9 +2,10 @@ const math = @import("index.zig");
 
 pub fn nan(comptime T: type) T {
     return switch (T) {
-        f16 => @bitCast(f16, math.nan_u16),
-        f32 => @bitCast(f32, math.nan_u32),
-        f64 => @bitCast(f64, math.nan_u64),
+        f16 => math.nan_f16,
+        f32 => math.nan_f32,
+        f64 => math.nan_f64,
+        f128 => math.nan_f128,
         else => @compileError("nan not implemented for " ++ @typeName(T)),
     };
 }