diff --git a/std/math/fabs.zig b/std/math/fabs.zig index 9fad5644c3..a605f4f33f 100644 --- a/std/math/fabs.zig +++ b/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)))); +} diff --git a/std/math/index.zig b/std/math/index.zig index ccfac03038..20648139b8 100644 --- a/std/math/index.zig +++ b/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" { diff --git a/std/math/inf.zig b/std/math/inf.zig index 62f5ef7c0d..fb7a3489c5 100644 --- a/std/math/inf.zig +++ b/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)), }; } diff --git a/std/math/isinf.zig b/std/math/isinf.zig index e34e9c5971..b1e3f7795e 100644 --- a/std/math/isinf.zig +++ b/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))); } diff --git a/std/math/isnan.zig b/std/math/isnan.zig index 641da9e620..e8b03a1e34 100644 --- a/std/math/isnan.zig +++ b/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))); } diff --git a/std/math/nan.zig b/std/math/nan.zig index 2cbcbee81b..d3ad43da23 100644 --- a/std/math/nan.zig +++ b/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)), }; }