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