| ... | @@ -4,12 +4,22 @@ const assert = std.debug.assert; | ... | @@ -4,12 +4,22 @@ const assert = std.debug.assert; |
| 4 | | 4 | |
| 5 | pub fn copysign(comptime T: type, x: T, y: T) T { | 5 | pub fn copysign(comptime T: type, x: T, y: T) T { |
| 6 | return switch (T) { | 6 | return switch (T) { |
| | 7 | f16 => copysign16(x, y), |
| 7 | f32 => copysign32(x, y), | 8 | f32 => copysign32(x, y), |
| 8 | f64 => copysign64(x, y), | 9 | f64 => copysign64(x, y), |
| 9 | else => @compileError("copysign not implemented for " ++ @typeName(T)), | 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 | fn copysign32(x: f32, y: f32) f32 { | 23 | fn copysign32(x: f32, y: f32) f32 { |
| 14 | const ux = @bitCast(u32, x); | 24 | const ux = @bitCast(u32, x); |
| 15 | const uy = @bitCast(u32, y); | 25 | const uy = @bitCast(u32, y); |
| ... | @@ -29,10 +39,18 @@ fn copysign64(x: f64, y: f64) f64 { | ... | @@ -29,10 +39,18 @@ fn copysign64(x: f64, y: f64) f64 { |
| 29 | } | 39 | } |
| 30 | | 40 | |
| 31 | test "math.copysign" { | 41 | test "math.copysign" { |
| | 42 | assert(copysign(f16, 1.0, 1.0) == copysign16(1.0, 1.0)); |
| 32 | assert(copysign(f32, 1.0, 1.0) == copysign32(1.0, 1.0)); | 43 | assert(copysign(f32, 1.0, 1.0) == copysign32(1.0, 1.0)); |
| 33 | assert(copysign(f64, 1.0, 1.0) == copysign64(1.0, 1.0)); | 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 | test "math.copysign32" { | 54 | test "math.copysign32" { |
| 37 | assert(copysign32(5.0, 1.0) == 5.0); | 55 | assert(copysign32(5.0, 1.0) == 5.0); |
| 38 | assert(copysign32(5.0, -1.0) == -5.0); | 56 | assert(copysign32(5.0, -1.0) == -5.0); |