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