| author | |
| committer | |
| log | bd282d6cca226c0b02af193f9c3cf0da5f6ea46d |
| tree | 5286470c43ef6c7f6530bf8518b0356e44a6ca3a |
| parent | 22b7312460c89f8fc9dad9674776d4ca3b40acd7 |
| parent | 30cfc0ab2c56ad73dca9b9935731d10010c93b32 |
| signature |
improve std.math f16 support14 files changed, 191 insertions(+), 2 deletions(-)
std/math/copysign.zig+18| ... | ... | @@ -4,12 +4,22 @@ const assert = std.debug.assert; |
| 4 | 4 | |
| 5 | 5 | pub fn copysign(comptime T: type, x: T, y: T) T { |
| 6 | 6 | return switch (T) { |
| 7 | f16 => copysign16(x, y), | |
| 7 | 8 | f32 => copysign32(x, y), |
| 8 | 9 | f64 => copysign64(x, y), |
| 9 | 10 | else => @compileError("copysign not implemented for " ++ @typeName(T)), |
| 10 | 11 | }; |
| 11 | 12 | } |
| 12 | 13 | |
| 14 | fn copysign16(x: f16, y: f16) f16 { | |
| 15 | const ux = @bitCast(u16, x); | |
| 16 | const uy = @bitCast(u16, y); | |
| 17 | ||
| 18 | const h1 = ux & (@maxValue(u16) / 2); | |
| 19 | const h2 = uy & (u16(1) << 15); | |
| 20 | return @bitCast(f16, h1 | h2); | |
| 21 | } | |
| 22 | ||
| 13 | 23 | fn copysign32(x: f32, y: f32) f32 { |
| 14 | 24 | const ux = @bitCast(u32, x); |
| 15 | 25 | const uy = @bitCast(u32, y); |
| ... | ... | @@ -29,10 +39,18 @@ fn copysign64(x: f64, y: f64) f64 { |
| 29 | 39 | } |
| 30 | 40 | |
| 31 | 41 | test "math.copysign" { |
| 42 | assert(copysign(f16, 1.0, 1.0) == copysign16(1.0, 1.0)); | |
| 32 | 43 | assert(copysign(f32, 1.0, 1.0) == copysign32(1.0, 1.0)); |
| 33 | 44 | assert(copysign(f64, 1.0, 1.0) == copysign64(1.0, 1.0)); |
| 34 | 45 | } |
| 35 | 46 | |
| 47 | test "math.copysign16" { | |
| 48 | assert(copysign16(5.0, 1.0) == 5.0); | |
| 49 | assert(copysign16(5.0, -1.0) == -5.0); | |
| 50 | assert(copysign16(-5.0, -1.0) == -5.0); | |
| 51 | assert(copysign16(-5.0, 1.0) == 5.0); | |
| 52 | } | |
| 53 | ||
| 36 | 54 | test "math.copysign32" { |
| 37 | 55 | assert(copysign32(5.0, 1.0) == 5.0); |
| 38 | 56 | assert(copysign32(5.0, -1.0) == -5.0); |
std/math/fabs.zig+19| ... | ... | @@ -10,12 +10,19 @@ const assert = std.debug.assert; |
| 10 | 10 | pub fn fabs(x: var) @typeOf(x) { |
| 11 | 11 | const T = @typeOf(x); |
| 12 | 12 | return switch (T) { |
| 13 | f16 => fabs16(x), | |
| 13 | 14 | f32 => fabs32(x), |
| 14 | 15 | f64 => fabs64(x), |
| 15 | 16 | else => @compileError("fabs not implemented for " ++ @typeName(T)), |
| 16 | 17 | }; |
| 17 | 18 | } |
| 18 | 19 | |
| 20 | fn fabs16(x: f16) f16 { | |
| 21 | var u = @bitCast(u16, x); | |
| 22 | u &= 0x7FFF; | |
| 23 | return @bitCast(f16, u); | |
| 24 | } | |
| 25 | ||
| 19 | 26 | fn fabs32(x: f32) f32 { |
| 20 | 27 | var u = @bitCast(u32, x); |
| 21 | 28 | u &= 0x7FFFFFFF; |
| ... | ... | @@ -29,10 +36,16 @@ fn fabs64(x: f64) f64 { |
| 29 | 36 | } |
| 30 | 37 | |
| 31 | 38 | test "math.fabs" { |
| 39 | assert(fabs(f16(1.0)) == fabs16(1.0)); | |
| 32 | 40 | assert(fabs(f32(1.0)) == fabs32(1.0)); |
| 33 | 41 | assert(fabs(f64(1.0)) == fabs64(1.0)); |
| 34 | 42 | } |
| 35 | 43 | |
| 44 | test "math.fabs16" { | |
| 45 | assert(fabs16(1.0) == 1.0); | |
| 46 | assert(fabs16(-1.0) == 1.0); | |
| 47 | } | |
| 48 | ||
| 36 | 49 | test "math.fabs32" { |
| 37 | 50 | assert(fabs32(1.0) == 1.0); |
| 38 | 51 | assert(fabs32(-1.0) == 1.0); |
| ... | ... | @@ -43,6 +56,12 @@ test "math.fabs64" { |
| 43 | 56 | assert(fabs64(-1.0) == 1.0); |
| 44 | 57 | } |
| 45 | 58 | |
| 59 | test "math.fabs16.special" { | |
| 60 | assert(math.isPositiveInf(fabs(math.inf(f16)))); | |
| 61 | assert(math.isPositiveInf(fabs(-math.inf(f16)))); | |
| 62 | assert(math.isNan(fabs(math.nan(f16)))); | |
| 63 | } | |
| 64 | ||
| 46 | 65 | test "math.fabs32.special" { |
| 47 | 66 | assert(math.isPositiveInf(fabs(math.inf(f32)))); |
| 48 | 67 | assert(math.isPositiveInf(fabs(-math.inf(f32)))); |
std/math/floor.zig+50| ... | ... | @@ -12,12 +12,47 @@ const math = std.math; |
| 12 | 12 | pub fn floor(x: var) @typeOf(x) { |
| 13 | 13 | const T = @typeOf(x); |
| 14 | 14 | return switch (T) { |
| 15 | f16 => floor16(x), | |
| 15 | 16 | f32 => floor32(x), |
| 16 | 17 | f64 => floor64(x), |
| 17 | 18 | else => @compileError("floor not implemented for " ++ @typeName(T)), |
| 18 | 19 | }; |
| 19 | 20 | } |
| 20 | 21 | |
| 22 | fn floor16(x: f16) f16 { | |
| 23 | var u = @bitCast(u16, x); | |
| 24 | const e = @intCast(i16, (u >> 10) & 31) - 15; | |
| 25 | var m: u16 = undefined; | |
| 26 | ||
| 27 | // TODO: Shouldn't need this explicit check. | |
| 28 | if (x == 0.0) { | |
| 29 | return x; | |
| 30 | } | |
| 31 | ||
| 32 | if (e >= 10) { | |
| 33 | return x; | |
| 34 | } | |
| 35 | ||
| 36 | if (e >= 0) { | |
| 37 | m = u16(1023) >> @intCast(u4, e); | |
| 38 | if (u & m == 0) { | |
| 39 | return x; | |
| 40 | } | |
| 41 | math.forceEval(x + 0x1.0p120); | |
| 42 | if (u >> 15 != 0) { | |
| 43 | u += m; | |
| 44 | } | |
| 45 | return @bitCast(f16, u & ~m); | |
| 46 | } else { | |
| 47 | math.forceEval(x + 0x1.0p120); | |
| 48 | if (u >> 15 == 0) { | |
| 49 | return 0.0; | |
| 50 | } else { | |
| 51 | return -1.0; | |
| 52 | } | |
| 53 | } | |
| 54 | } | |
| 55 | ||
| 21 | 56 | fn floor32(x: f32) f32 { |
| 22 | 57 | var u = @bitCast(u32, x); |
| 23 | 58 | const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; |
| ... | ... | @@ -84,10 +119,17 @@ fn floor64(x: f64) f64 { |
| 84 | 119 | } |
| 85 | 120 | |
| 86 | 121 | test "math.floor" { |
| 122 | assert(floor(f16(1.3)) == floor16(1.3)); | |
| 87 | 123 | assert(floor(f32(1.3)) == floor32(1.3)); |
| 88 | 124 | assert(floor(f64(1.3)) == floor64(1.3)); |
| 89 | 125 | } |
| 90 | 126 | |
| 127 | test "math.floor16" { | |
| 128 | assert(floor16(1.3) == 1.0); | |
| 129 | assert(floor16(-1.3) == -2.0); | |
| 130 | assert(floor16(0.2) == 0.0); | |
| 131 | } | |
| 132 | ||
| 91 | 133 | test "math.floor32" { |
| 92 | 134 | assert(floor32(1.3) == 1.0); |
| 93 | 135 | assert(floor32(-1.3) == -2.0); |
| ... | ... | @@ -100,6 +142,14 @@ test "math.floor64" { |
| 100 | 142 | assert(floor64(0.2) == 0.0); |
| 101 | 143 | } |
| 102 | 144 | |
| 145 | test "math.floor16.special" { | |
| 146 | assert(floor16(0.0) == 0.0); | |
| 147 | assert(floor16(-0.0) == -0.0); | |
| 148 | assert(math.isPositiveInf(floor16(math.inf(f16)))); | |
| 149 | assert(math.isNegativeInf(floor16(-math.inf(f16)))); | |
| 150 | assert(math.isNan(floor16(math.nan(f16)))); | |
| 151 | } | |
| 152 | ||
| 103 | 153 | test "math.floor32.special" { |
| 104 | 154 | assert(floor32(0.0) == 0.0); |
| 105 | 155 | assert(floor32(-0.0) == -0.0); |
std/math/index.zig+17| ... | ... | @@ -19,6 +19,18 @@ pub const f32_max = 3.40282346638528859812e+38; |
| 19 | 19 | pub const f32_epsilon = 1.1920928955078125e-07; |
| 20 | 20 | pub const f32_toint = 1.0 / f32_epsilon; |
| 21 | 21 | |
| 22 | pub const f16_true_min = 0.000000059604644775390625; // 2**-24 | |
| 23 | pub const f16_min = 0.00006103515625; // 2**-14 | |
| 24 | pub const f16_max = 65504; | |
| 25 | pub const f16_epsilon = 0.0009765625; // 2**-10 | |
| 26 | pub const f16_toint = 1.0 / f16_epsilon; | |
| 27 | ||
| 28 | pub const nan_u16 = u16(0x7C01); | |
| 29 | pub const nan_f16 = @bitCast(f16, nan_u16); | |
| 30 | ||
| 31 | pub const inf_u16 = u16(0x7C00); | |
| 32 | pub const inf_f16 = @bitCast(f16, inf_u16); | |
| 33 | ||
| 22 | 34 | pub const nan_u32 = u32(0x7F800001); |
| 23 | 35 | pub const nan_f32 = @bitCast(f32, nan_u32); |
| 24 | 36 | |
| ... | ... | @@ -44,6 +56,11 @@ pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) bool { |
| 44 | 56 | pub fn forceEval(value: var) void { |
| 45 | 57 | const T = @typeOf(value); |
| 46 | 58 | switch (T) { |
| 59 | f16 => { | |
| 60 | var x: f16 = undefined; | |
| 61 | const p = @ptrCast(*volatile f16, &x); | |
| 62 | p.* = x; | |
| 63 | }, | |
| 47 | 64 | f32 => { |
| 48 | 65 | var x: f32 = undefined; |
| 49 | 66 | const p = @ptrCast(*volatile f32, &x); |
std/math/inf.zig+1-1| ... | ... | @@ -1,9 +1,9 @@ |
| 1 | 1 | const std = @import("../index.zig"); |
| 2 | 2 | const math = std.math; |
| 3 | const assert = std.debug.assert; | |
| 4 | 3 | |
| 5 | 4 | pub fn inf(comptime T: type) T { |
| 6 | 5 | return switch (T) { |
| 6 | f16 => @bitCast(f16, math.inf_u16), | |
| 7 | 7 | f32 => @bitCast(f32, math.inf_u32), |
| 8 | 8 | f64 => @bitCast(f64, math.inf_u64), |
| 9 | 9 | else => @compileError("inf not implemented for " ++ @typeName(T)), |
std/math/isfinite.zig+8| ... | ... | @@ -5,6 +5,10 @@ const assert = std.debug.assert; |
| 5 | 5 | pub fn isFinite(x: var) bool { |
| 6 | 6 | const T = @typeOf(x); |
| 7 | 7 | switch (T) { |
| 8 | f16 => { | |
| 9 | const bits = @bitCast(u16, x); | |
| 10 | return bits & 0x7FFF < 0x7C00; | |
| 11 | }, | |
| 8 | 12 | f32 => { |
| 9 | 13 | const bits = @bitCast(u32, x); |
| 10 | 14 | return bits & 0x7FFFFFFF < 0x7F800000; |
| ... | ... | @@ -20,10 +24,14 @@ pub fn isFinite(x: var) bool { |
| 20 | 24 | } |
| 21 | 25 | |
| 22 | 26 | test "math.isFinite" { |
| 27 | assert(isFinite(f16(0.0))); | |
| 28 | assert(isFinite(f16(-0.0))); | |
| 23 | 29 | assert(isFinite(f32(0.0))); |
| 24 | 30 | assert(isFinite(f32(-0.0))); |
| 25 | 31 | assert(isFinite(f64(0.0))); |
| 26 | 32 | assert(isFinite(f64(-0.0))); |
| 33 | assert(!isFinite(math.inf(f16))); | |
| 34 | assert(!isFinite(-math.inf(f16))); | |
| 27 | 35 | assert(!isFinite(math.inf(f32))); |
| 28 | 36 | assert(!isFinite(-math.inf(f32))); |
| 29 | 37 | assert(!isFinite(math.inf(f64))); |
std/math/isinf.zig+22| ... | ... | @@ -5,6 +5,10 @@ const assert = std.debug.assert; |
| 5 | 5 | pub fn isInf(x: var) bool { |
| 6 | 6 | const T = @typeOf(x); |
| 7 | 7 | switch (T) { |
| 8 | f16 => { | |
| 9 | const bits = @bitCast(u16, x); | |
| 10 | return bits & 0x7FFF == 0x7C00; | |
| 11 | }, | |
| 8 | 12 | f32 => { |
| 9 | 13 | const bits = @bitCast(u32, x); |
| 10 | 14 | return bits & 0x7FFFFFFF == 0x7F800000; |
| ... | ... | @@ -22,6 +26,9 @@ pub fn isInf(x: var) bool { |
| 22 | 26 | pub fn isPositiveInf(x: var) bool { |
| 23 | 27 | const T = @typeOf(x); |
| 24 | 28 | switch (T) { |
| 29 | f16 => { | |
| 30 | return @bitCast(u16, x) == 0x7C00; | |
| 31 | }, | |
| 25 | 32 | f32 => { |
| 26 | 33 | return @bitCast(u32, x) == 0x7F800000; |
| 27 | 34 | }, |
| ... | ... | @@ -37,6 +44,9 @@ pub fn isPositiveInf(x: var) bool { |
| 37 | 44 | pub fn isNegativeInf(x: var) bool { |
| 38 | 45 | const T = @typeOf(x); |
| 39 | 46 | switch (T) { |
| 47 | f16 => { | |
| 48 | return @bitCast(u16, x) == 0xFC00; | |
| 49 | }, | |
| 40 | 50 | f32 => { |
| 41 | 51 | return @bitCast(u32, x) == 0xFF800000; |
| 42 | 52 | }, |
| ... | ... | @@ -50,10 +60,14 @@ pub fn isNegativeInf(x: var) bool { |
| 50 | 60 | } |
| 51 | 61 | |
| 52 | 62 | test "math.isInf" { |
| 63 | assert(!isInf(f16(0.0))); | |
| 64 | assert(!isInf(f16(-0.0))); | |
| 53 | 65 | assert(!isInf(f32(0.0))); |
| 54 | 66 | assert(!isInf(f32(-0.0))); |
| 55 | 67 | assert(!isInf(f64(0.0))); |
| 56 | 68 | assert(!isInf(f64(-0.0))); |
| 69 | assert(isInf(math.inf(f16))); | |
| 70 | assert(isInf(-math.inf(f16))); | |
| 57 | 71 | assert(isInf(math.inf(f32))); |
| 58 | 72 | assert(isInf(-math.inf(f32))); |
| 59 | 73 | assert(isInf(math.inf(f64))); |
| ... | ... | @@ -61,10 +75,14 @@ test "math.isInf" { |
| 61 | 75 | } |
| 62 | 76 | |
| 63 | 77 | test "math.isPositiveInf" { |
| 78 | assert(!isPositiveInf(f16(0.0))); | |
| 79 | assert(!isPositiveInf(f16(-0.0))); | |
| 64 | 80 | assert(!isPositiveInf(f32(0.0))); |
| 65 | 81 | assert(!isPositiveInf(f32(-0.0))); |
| 66 | 82 | assert(!isPositiveInf(f64(0.0))); |
| 67 | 83 | assert(!isPositiveInf(f64(-0.0))); |
| 84 | assert(isPositiveInf(math.inf(f16))); | |
| 85 | assert(!isPositiveInf(-math.inf(f16))); | |
| 68 | 86 | assert(isPositiveInf(math.inf(f32))); |
| 69 | 87 | assert(!isPositiveInf(-math.inf(f32))); |
| 70 | 88 | assert(isPositiveInf(math.inf(f64))); |
| ... | ... | @@ -72,10 +90,14 @@ test "math.isPositiveInf" { |
| 72 | 90 | } |
| 73 | 91 | |
| 74 | 92 | test "math.isNegativeInf" { |
| 93 | assert(!isNegativeInf(f16(0.0))); | |
| 94 | assert(!isNegativeInf(f16(-0.0))); | |
| 75 | 95 | assert(!isNegativeInf(f32(0.0))); |
| 76 | 96 | assert(!isNegativeInf(f32(-0.0))); |
| 77 | 97 | assert(!isNegativeInf(f64(0.0))); |
| 78 | 98 | assert(!isNegativeInf(f64(-0.0))); |
| 99 | assert(!isNegativeInf(math.inf(f16))); | |
| 100 | assert(isNegativeInf(-math.inf(f16))); | |
| 79 | 101 | assert(!isNegativeInf(math.inf(f32))); |
| 80 | 102 | assert(isNegativeInf(-math.inf(f32))); |
| 81 | 103 | assert(!isNegativeInf(math.inf(f64))); |
std/math/isnan.zig+6| ... | ... | @@ -5,6 +5,10 @@ const assert = std.debug.assert; |
| 5 | 5 | pub fn isNan(x: var) bool { |
| 6 | 6 | const T = @typeOf(x); |
| 7 | 7 | switch (T) { |
| 8 | f16 => { | |
| 9 | const bits = @bitCast(u16, x); | |
| 10 | return (bits & 0x7fff) > 0x7c00; | |
| 11 | }, | |
| 8 | 12 | f32 => { |
| 9 | 13 | const bits = @bitCast(u32, x); |
| 10 | 14 | return bits & 0x7FFFFFFF > 0x7F800000; |
| ... | ... | @@ -26,8 +30,10 @@ pub fn isSignalNan(x: var) bool { |
| 26 | 30 | } |
| 27 | 31 | |
| 28 | 32 | test "math.isNan" { |
| 33 | assert(isNan(math.nan(f16))); | |
| 29 | 34 | assert(isNan(math.nan(f32))); |
| 30 | 35 | assert(isNan(math.nan(f64))); |
| 36 | assert(!isNan(f16(1.0))); | |
| 31 | 37 | assert(!isNan(f32(1.0))); |
| 32 | 38 | assert(!isNan(f64(1.0))); |
| 33 | 39 | } |
std/math/isnormal.zig+9| ... | ... | @@ -5,6 +5,10 @@ const assert = std.debug.assert; |
| 5 | 5 | pub fn isNormal(x: var) bool { |
| 6 | 6 | const T = @typeOf(x); |
| 7 | 7 | switch (T) { |
| 8 | f16 => { | |
| 9 | const bits = @bitCast(u16, x); | |
| 10 | return (bits + 1024) & 0x7FFF >= 2048; | |
| 11 | }, | |
| 8 | 12 | f32 => { |
| 9 | 13 | const bits = @bitCast(u32, x); |
| 10 | 14 | return (bits + 0x00800000) & 0x7FFFFFFF >= 0x01000000; |
| ... | ... | @@ -20,8 +24,13 @@ pub fn isNormal(x: var) bool { |
| 20 | 24 | } |
| 21 | 25 | |
| 22 | 26 | test "math.isNormal" { |
| 27 | assert(!isNormal(math.nan(f16))); | |
| 23 | 28 | assert(!isNormal(math.nan(f32))); |
| 24 | 29 | assert(!isNormal(math.nan(f64))); |
| 30 | assert(!isNormal(f16(0))); | |
| 31 | assert(!isNormal(f32(0))); | |
| 32 | assert(!isNormal(f64(0))); | |
| 33 | assert(isNormal(f16(1.0))); | |
| 25 | 34 | assert(isNormal(f32(1.0))); |
| 26 | 35 | assert(isNormal(f64(1.0))); |
| 27 | 36 | } |
std/math/nan.zig+2| ... | ... | @@ -2,6 +2,7 @@ const math = @import("index.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn nan(comptime T: type) T { |
| 4 | 4 | return switch (T) { |
| 5 | f16 => @bitCast(f16, math.nan_u16), | |
| 5 | 6 | f32 => @bitCast(f32, math.nan_u32), |
| 6 | 7 | f64 => @bitCast(f64, math.nan_u64), |
| 7 | 8 | else => @compileError("nan not implemented for " ++ @typeName(T)), |
| ... | ... | @@ -12,6 +13,7 @@ pub fn nan(comptime T: type) T { |
| 12 | 13 | // representation in the future when required. |
| 13 | 14 | pub fn snan(comptime T: type) T { |
| 14 | 15 | return switch (T) { |
| 16 | f16 => @bitCast(f16, math.nan_u16), | |
| 15 | 17 | f32 => @bitCast(f32, math.nan_u32), |
| 16 | 18 | f64 => @bitCast(f64, math.nan_u64), |
| 17 | 19 | else => @compileError("snan not implemented for " ++ @typeName(T)), |
std/math/signbit.zig+12| ... | ... | @@ -5,12 +5,18 @@ const assert = std.debug.assert; |
| 5 | 5 | pub fn signbit(x: var) bool { |
| 6 | 6 | const T = @typeOf(x); |
| 7 | 7 | return switch (T) { |
| 8 | f16 => signbit16(x), | |
| 8 | 9 | f32 => signbit32(x), |
| 9 | 10 | f64 => signbit64(x), |
| 10 | 11 | else => @compileError("signbit not implemented for " ++ @typeName(T)), |
| 11 | 12 | }; |
| 12 | 13 | } |
| 13 | 14 | |
| 15 | fn signbit16(x: f16) bool { | |
| 16 | const bits = @bitCast(u16, x); | |
| 17 | return bits >> 15 != 0; | |
| 18 | } | |
| 19 | ||
| 14 | 20 | fn signbit32(x: f32) bool { |
| 15 | 21 | const bits = @bitCast(u32, x); |
| 16 | 22 | return bits >> 31 != 0; |
| ... | ... | @@ -22,10 +28,16 @@ fn signbit64(x: f64) bool { |
| 22 | 28 | } |
| 23 | 29 | |
| 24 | 30 | test "math.signbit" { |
| 31 | assert(signbit(f16(4.0)) == signbit16(4.0)); | |
| 25 | 32 | assert(signbit(f32(4.0)) == signbit32(4.0)); |
| 26 | 33 | assert(signbit(f64(4.0)) == signbit64(4.0)); |
| 27 | 34 | } |
| 28 | 35 | |
| 36 | test "math.signbit16" { | |
| 37 | assert(!signbit16(4.0)); | |
| 38 | assert(signbit16(-3.0)); | |
| 39 | } | |
| 40 | ||
| 29 | 41 | test "math.signbit32" { |
| 30 | 42 | assert(!signbit32(4.0)); |
| 31 | 43 | assert(signbit32(-3.0)); |
std/math/sqrt.zig+23| ... | ... | @@ -31,10 +31,25 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | test "math.sqrt" { |
| 34 | assert(sqrt(f16(0.0)) == @sqrt(f16, 0.0)); | |
| 34 | 35 | assert(sqrt(f32(0.0)) == @sqrt(f32, 0.0)); |
| 35 | 36 | assert(sqrt(f64(0.0)) == @sqrt(f64, 0.0)); |
| 36 | 37 | } |
| 37 | 38 | |
| 39 | test "math.sqrt16" { | |
| 40 | const epsilon = 0.000001; | |
| 41 | ||
| 42 | assert(@sqrt(f16, 0.0) == 0.0); | |
| 43 | assert(math.approxEq(f16, @sqrt(f16, 2.0), 1.414214, epsilon)); | |
| 44 | assert(math.approxEq(f16, @sqrt(f16, 3.6), 1.897367, epsilon)); | |
| 45 | assert(@sqrt(f16, 4.0) == 2.0); | |
| 46 | assert(math.approxEq(f16, @sqrt(f16, 7.539840), 2.745877, epsilon)); | |
| 47 | assert(math.approxEq(f16, @sqrt(f16, 19.230934), 4.385309, epsilon)); | |
| 48 | assert(@sqrt(f16, 64.0) == 8.0); | |
| 49 | assert(math.approxEq(f16, @sqrt(f16, 64.1), 8.006248, epsilon)); | |
| 50 | assert(math.approxEq(f16, @sqrt(f16, 8942.230469), 94.563370, epsilon)); | |
| 51 | } | |
| 52 | ||
| 38 | 53 | test "math.sqrt32" { |
| 39 | 54 | const epsilon = 0.000001; |
| 40 | 55 | |
| ... | ... | @@ -63,6 +78,14 @@ test "math.sqrt64" { |
| 63 | 78 | assert(math.approxEq(f64, @sqrt(f64, 8942.230469), 94.563367, epsilon)); |
| 64 | 79 | } |
| 65 | 80 | |
| 81 | test "math.sqrt16.special" { | |
| 82 | assert(math.isPositiveInf(@sqrt(f16, math.inf(f16)))); | |
| 83 | assert(@sqrt(f16, 0.0) == 0.0); | |
| 84 | assert(@sqrt(f16, -0.0) == -0.0); | |
| 85 | assert(math.isNan(@sqrt(f16, -1.0))); | |
| 86 | assert(math.isNan(@sqrt(f16, math.nan(f16)))); | |
| 87 | } | |
| 88 | ||
| 66 | 89 | test "math.sqrt32.special" { |
| 67 | 90 | assert(math.isPositiveInf(@sqrt(f32, math.inf(f32)))); |
| 68 | 91 | assert(@sqrt(f32, 0.0) == 0.0); |
std/special/builtin.zig+3-1| ... | ... | @@ -210,7 +210,9 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 210 | 210 | } |
| 211 | 211 | |
| 212 | 212 | fn isNan(comptime T: type, bits: T) bool { |
| 213 | if (T == u32) { | |
| 213 | if (T == u16) { | |
| 214 | return (bits & 0x7fff) > 0x7c00; | |
| 215 | } else if (T == u32) { | |
| 214 | 216 | return (bits & 0x7fffffff) > 0x7f800000; |
| 215 | 217 | } else if (T == u64) { |
| 216 | 218 | return (bits & (@maxValue(u64) >> 1)) > (u64(0x7ff) << 52); |
std/special/compiler_rt/extendXfYf2_test.zig+1| ... | ... | @@ -88,6 +88,7 @@ test "extenddftf2" { |
| 88 | 88 | test "extendhfsf2" { |
| 89 | 89 | test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN |
| 90 | 90 | test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN |
| 91 | test__extendhfsf2(0x7c01, 0x7f802000); // sNaN | |
| 91 | 92 | |
| 92 | 93 | test__extendhfsf2(0, 0); // 0 |
| 93 | 94 | test__extendhfsf2(0x8000, 0x80000000); // -0 |