| author | |
| committer | |
| log | 60fc18bd1c154f3c728a147c4574b5db8a17f08e |
| tree | b5cbc46487b23e553715aba706e85cedb7c7eef5 |
| parent | f74e10cd4722512ac671f574b3d274ab48abb1a7 |
This corrects comparisons between negative numbers.2 files changed, 34 insertions(+), 1 deletions(-)
lib/compiler_rt/comparef.zig+12-1| ... | @@ -89,7 +89,7 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { | ... | @@ -89,7 +89,7 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { |
| 89 | } else { | 89 | } else { |
| 90 | const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); | 90 | const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); |
| 91 | const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); | 91 | const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); |
| 92 | if (a_fraction < b_fraction) { | 92 | if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { |
| 93 | return .Less; | 93 | return .Less; |
| 94 | } else { | 94 | } else { |
| 95 | return .Greater; | 95 | return .Greater; |
| ... | @@ -97,6 +97,17 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { | ... | @@ -97,6 +97,17 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | test "cmp_f80" { | ||
| 101 | inline for (.{ LE, GE }) |RT| { | ||
| 102 | try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal); | ||
| 103 | try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal); | ||
| 104 | try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less); | ||
| 105 | try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater); | ||
| 106 | try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater); | ||
| 107 | try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 100 | pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { | 111 | pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { |
| 101 | const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); | 112 | const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); |
| 102 | 113 |
test/behavior/floatop.zig+22| ... | @@ -70,6 +70,28 @@ fn testDifferentSizedFloatComparisons() !void { | ... | @@ -70,6 +70,28 @@ fn testDifferentSizedFloatComparisons() !void { |
| 70 | try expect(a < b); | 70 | try expect(a < b); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | test "f80 comparisons" { | ||
| 74 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 75 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 76 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 77 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 78 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 79 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 80 | |||
| 81 | try expect(compareF80(0.0, .eq, -0.0)); | ||
| 82 | try expect(compareF80(0.0, .lte, -0.0)); | ||
| 83 | try expect(compareF80(0.0, .gte, -0.0)); | ||
| 84 | try expect(compareF80(1.0, .neq, -1.0)); | ||
| 85 | try expect(compareF80(2.0, .lt, 4.0)); | ||
| 86 | try expect(compareF80(2.0, .lte, 4.0)); | ||
| 87 | try expect(compareF80(-2.0, .gt, -4.0)); | ||
| 88 | try expect(compareF80(-2.0, .gte, -4.0)); | ||
| 89 | } | ||
| 90 | |||
| 91 | fn compareF80(x: f80, op: math.CompareOperator, y: f80) bool { | ||
| 92 | return math.compare(x, op, y); | ||
| 93 | } | ||
| 94 | |||
| 73 | // TODO This is waiting on library support for the Windows build (not sure why the other's don't need it) | 95 | // TODO This is waiting on library support for the Windows build (not sure why the other's don't need it) |
| 74 | //test "@nearbyint" { | 96 | //test "@nearbyint" { |
| 75 | // comptime testNearbyInt(); | 97 | // comptime testNearbyInt(); |