From 27b02413dc3dacc7d784fe84ff8ba6cb0361842d Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 30 Jun 2018 01:44:54 +0200 Subject: [PATCH] add std.math f16 nan support refs #1122 --- std/math/index.zig | 3 +++ std/math/isnan.zig | 6 ++++++ std/math/nan.zig | 2 ++ std/special/builtin.zig | 4 +++- std/special/compiler_rt/extendXfYf2_test.zig | 1 + 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/std/math/index.zig b/std/math/index.zig index e987274f71..df8271fbcf 100644 --- a/std/math/index.zig +++ b/std/math/index.zig @@ -25,6 +25,9 @@ pub const f16_max = 65504; pub const f16_epsilon = 0.0009765625; // 2**-10 pub const f16_toint = 1.0 / f16_epsilon; +pub const nan_u16 = u16(0x7C01); +pub const nan_f16 = @bitCast(f16, nan_u16); + pub const nan_u32 = u32(0x7F800001); pub const nan_f32 = @bitCast(f32, nan_u32); diff --git a/std/math/isnan.zig b/std/math/isnan.zig index 67971e3d0c..ef3002d8e1 100644 --- a/std/math/isnan.zig +++ b/std/math/isnan.zig @@ -5,6 +5,10 @@ const assert = std.debug.assert; pub fn isNan(x: var) bool { const T = @typeOf(x); switch (T) { + f16 => { + const bits = @bitCast(u16, x); + return (bits & 0x7fff) > 0x7c00; + }, f32 => { const bits = @bitCast(u32, x); return bits & 0x7FFFFFFF > 0x7F800000; @@ -26,8 +30,10 @@ pub fn isSignalNan(x: var) bool { } test "math.isNan" { + assert(isNan(math.nan(f16))); assert(isNan(math.nan(f32))); assert(isNan(math.nan(f64))); + assert(!isNan(f16(1.0))); assert(!isNan(f32(1.0))); assert(!isNan(f64(1.0))); } diff --git a/std/math/nan.zig b/std/math/nan.zig index 22461711d0..2cbcbee81b 100644 --- a/std/math/nan.zig +++ b/std/math/nan.zig @@ -2,6 +2,7 @@ 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), else => @compileError("nan not implemented for " ++ @typeName(T)), @@ -12,6 +13,7 @@ pub fn nan(comptime T: type) T { // representation in the future when required. pub fn snan(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), else => @compileError("snan not implemented for " ++ @typeName(T)), diff --git a/std/special/builtin.zig b/std/special/builtin.zig index 07e735d931..56e578030b 100644 --- a/std/special/builtin.zig +++ b/std/special/builtin.zig @@ -210,7 +210,9 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { } fn isNan(comptime T: type, bits: T) bool { - if (T == u32) { + if (T == u16) { + return (bits & 0x7fff) > 0x7c00; + } else if (T == u32) { return (bits & 0x7fffffff) > 0x7f800000; } else if (T == u64) { return (bits & (@maxValue(u64) >> 1)) > (u64(0x7ff) << 52); diff --git a/std/special/compiler_rt/extendXfYf2_test.zig b/std/special/compiler_rt/extendXfYf2_test.zig index 0168de12a5..185c83a0ef 100644 --- a/std/special/compiler_rt/extendXfYf2_test.zig +++ b/std/special/compiler_rt/extendXfYf2_test.zig @@ -88,6 +88,7 @@ test "extenddftf2" { test "extendhfsf2" { test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN + test__extendhfsf2(0x7c01, 0x7f802000); // sNaN test__extendhfsf2(0, 0); // 0 test__extendhfsf2(0x8000, 0x80000000); // -0