diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index 8a3dd43727..51e97abf61 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -534,13 +534,14 @@ pub const Int = struct { return out_stream.writeAll(str); } - /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. - pub fn cmpAbs(a: Int, b: Int) i8 { + /// Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| == + /// |b| or |a| > |b| respectively. + pub fn cmpAbs(a: Int, b: Int) math.Order { if (a.len() < b.len()) { - return -1; + return .lt; } if (a.len() > b.len()) { - return 1; + return .gt; } var i: usize = a.len() - 1; @@ -551,21 +552,26 @@ pub const Int = struct { } if (a.limbs[i] < b.limbs[i]) { - return -1; + return .lt; } else if (a.limbs[i] > b.limbs[i]) { - return 1; + return .gt; } else { - return 0; + return .eq; } } - /// Returns -1, 0, 1 if a < b, a == b or a > b respectively. - pub fn cmp(a: Int, b: Int) i8 { + /// Returns math.Order.lt, math.Order.eq, math.Order.gt if a < b, a == b or a + /// > b respectively. + pub fn cmp(a: Int, b: Int) math.Order { if (a.isPositive() != b.isPositive()) { - return if (a.isPositive()) @as(i8, 1) else -1; + return if (a.isPositive()) .gt else .lt; } else { const r = cmpAbs(a, b); - return if (a.isPositive()) r else -r; + return if (a.isPositive()) r else switch (r) { + .lt => math.Order.gt, + .eq => math.Order.eq, + .gt => math.Order.lt, + }; } } @@ -576,12 +582,12 @@ pub const Int = struct { /// Returns true if |a| == |b|. pub fn eqAbs(a: Int, b: Int) bool { - return cmpAbs(a, b) == 0; + return cmpAbs(a, b) == .eq; } /// Returns true if a == b. pub fn eq(a: Int, b: Int) bool { - return cmp(a, b) == 0; + return cmp(a, b) == .eq; } // Normalize a possible sequence of leading zeros. @@ -694,7 +700,7 @@ pub const Int = struct { } else { if (a.isPositive()) { // (a) - (b) => a - b - if (a.cmp(b) >= 0) { + if (a.cmp(b) != .lt) { try r.ensureCapacity(a.len() + 1); llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); r.normalize(a.len()); @@ -707,7 +713,7 @@ pub const Int = struct { } } else { // (-a) - (-b) => -(a - b) - if (a.cmp(b) < 0) { + if (a.cmp(b) == .lt) { try r.ensureCapacity(a.len() + 1); llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); r.normalize(a.len()); @@ -1010,7 +1016,7 @@ pub const Int = struct { @panic("quo and rem cannot be same variable"); } - if (a.cmpAbs(b) < 0) { + if (a.cmpAbs(b) == .lt) { // quo may alias a so handle rem first try rem.copy(a); rem.setSign(a.isPositive() == b.isPositive()); @@ -1133,7 +1139,7 @@ pub const Int = struct { // 2. try tmp.shiftLeft(y.*, Limb.bit_count * (n - t)); - while (x.cmp(tmp) >= 0) { + while (x.cmp(tmp) != .lt) { q.limbs[n - t] += 1; try x.sub(x.*, tmp); } @@ -1164,7 +1170,7 @@ pub const Int = struct { r.limbs[2] = carry; r.normalize(3); - if (r.cmpAbs(tmp) <= 0) { + if (r.cmpAbs(tmp) != .gt) { break; } @@ -1719,8 +1725,8 @@ test "big.int compare" { var b = try Int.initSet(testing.allocator, 10); defer b.deinit(); - testing.expect(a.cmpAbs(b) == 1); - testing.expect(a.cmp(b) == -1); + testing.expect(a.cmpAbs(b) == .gt); + testing.expect(a.cmp(b) == .lt); } test "big.int compare similar" { @@ -1729,8 +1735,8 @@ test "big.int compare similar" { var b = try Int.initSet(testing.allocator, 0xffffffffeeeeeeeeffffffffeeeeeeef); defer b.deinit(); - testing.expect(a.cmpAbs(b) == -1); - testing.expect(b.cmpAbs(a) == 1); + testing.expect(a.cmpAbs(b) == .lt); + testing.expect(b.cmpAbs(a) == .gt); } test "big.int compare different limb size" { @@ -1739,8 +1745,8 @@ test "big.int compare different limb size" { var b = try Int.initSet(testing.allocator, 1); defer b.deinit(); - testing.expect(a.cmpAbs(b) == 1); - testing.expect(b.cmpAbs(a) == -1); + testing.expect(a.cmpAbs(b) == .gt); + testing.expect(b.cmpAbs(a) == .lt); } test "big.int compare multi-limb" { @@ -1749,8 +1755,8 @@ test "big.int compare multi-limb" { var b = try Int.initSet(testing.allocator, 0x7777777799999999ffffeeeeffffeeeeffffeeeee); defer b.deinit(); - testing.expect(a.cmpAbs(b) == 1); - testing.expect(a.cmp(b) == -1); + testing.expect(a.cmpAbs(b) == .gt); + testing.expect(a.cmp(b) == .lt); } test "big.int equality" { @@ -2726,9 +2732,9 @@ test "big.int var args" { const c = try Int.initSet(testing.allocator, 11); defer c.deinit(); - testing.expect(a.cmp(c) == 0); + testing.expect(a.cmp(c) == .eq); const d = try Int.initSet(testing.allocator, 14); defer d.deinit(); - testing.expect(a.cmp(d) <= 0); + testing.expect(a.cmp(d) != .gt); } diff --git a/lib/std/math/big/rational.zig b/lib/std/math/big/rational.zig index a57183a623..cf88558576 100644 --- a/lib/std/math/big/rational.zig +++ b/lib/std/math/big/rational.zig @@ -326,18 +326,20 @@ pub const Rational = struct { r.q.swap(&other.q); } - /// Returns -1, 0, 1 if a < b, a == b or a > b respectively. - pub fn cmp(a: Rational, b: Rational) !i8 { + /// Returns math.Order.lt, math.Order.eq, math.Order.gt if a < b, a == b or a + /// > b respectively. + pub fn cmp(a: Rational, b: Rational) !math.Order { return cmpInternal(a, b, true); } - /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. - pub fn cmpAbs(a: Rational, b: Rational) !i8 { + /// Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| == + /// |b| or |a| > |b| respectively. + pub fn cmpAbs(a: Rational, b: Rational) !math.Order { return cmpInternal(a, b, false); } // p/q > x/y iff p*y > x*q - fn cmpInternal(a: Rational, b: Rational, is_abs: bool) !i8 { + fn cmpInternal(a: Rational, b: Rational, is_abs: bool) !math.Order { // TODO: Would a div compare algorithm of sorts be viable and quicker? Can we avoid // the memory allocations here? var q = try Int.init(a.p.allocator.?); @@ -450,7 +452,7 @@ pub const Rational = struct { r.p.setSign(sign); const one = Int.initFixed(([_]Limb{1})[0..]); - if (a.cmp(one) != 0) { + if (a.cmp(one) != .eq) { var unused = try Int.init(r.p.allocator.?); defer unused.deinit(); @@ -505,7 +507,7 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { y.abs(); defer y.deinit(); - if (x.cmp(y) < 0) { + if (x.cmp(y) == .lt) { x.swap(&y); } @@ -573,7 +575,7 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { } // euclidean algorithm - debug.assert(x.cmp(y) >= 0); + debug.assert(x.cmp(y) != .lt); while (!y.eqZero()) { try Int.divTrunc(&T, r, x, y); @@ -874,11 +876,11 @@ test "big.rational cmp" { try a.setRatio(500, 231); try b.setRatio(18903, 8584); - testing.expect((try a.cmp(b)) < 0); + testing.expect((try a.cmp(b)) == .lt); try a.setRatio(890, 10); try b.setRatio(89, 1); - testing.expect((try a.cmp(b)) == 0); + testing.expect((try a.cmp(b)) == .eq); } test "big.rational add single-limb" { @@ -889,11 +891,11 @@ test "big.rational add single-limb" { try a.setRatio(500, 231); try b.setRatio(18903, 8584); - testing.expect((try a.cmp(b)) < 0); + testing.expect((try a.cmp(b)) == .lt); try a.setRatio(890, 10); try b.setRatio(89, 1); - testing.expect((try a.cmp(b)) == 0); + testing.expect((try a.cmp(b)) == .eq); } test "big.rational add" { @@ -909,7 +911,7 @@ test "big.rational add" { try a.add(a, b); try r.setRatio(984786924199, 290395044174); - testing.expect((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == .eq); } test "big.rational sub" { @@ -925,7 +927,7 @@ test "big.rational sub" { try a.sub(a, b); try r.setRatio(979040510045, 290395044174); - testing.expect((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == .eq); } test "big.rational mul" { @@ -941,7 +943,7 @@ test "big.rational mul" { try a.mul(a, b); try r.setRatio(571481443, 17082061422); - testing.expect((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == .eq); } test "big.rational div" { @@ -957,7 +959,7 @@ test "big.rational div" { try a.div(a, b); try r.setRatio(75531824394, 221015929); - testing.expect((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == .eq); } test "big.rational div" { @@ -970,11 +972,11 @@ test "big.rational div" { a.invert(); try r.setRatio(23341, 78923); - testing.expect((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == .eq); try a.setRatio(-78923, 23341); a.invert(); try r.setRatio(-23341, 78923); - testing.expect((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == .eq); }