Add f128 support for fabs, isinf, isnan, inf and nan functions

This commit is contained in:
Marc Tiehuis 2019-02-13 23:27:23 +13:00
parent be861a85c8
commit cf007e37b9
6 changed files with 66 additions and 7 deletions

View File

@ -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))));
}

View File

@ -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" {

View File

@ -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)),
};
}

View File

@ -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)));
}

View File

@ -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)));
}

View File

@ -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)),
};
}