Commit 27b02413dc

Ben Noordhuis <info@bnoordhuis.nl>
2018-06-30 01:44:54
add std.math f16 nan support
refs #1122
1 parent 61df5bc
Changed files (5)
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);
 
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)));
 }
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)),
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
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);