| ... | ... | @@ -534,13 +534,14 @@ pub const Int = struct { |
| 534 | 534 | return out_stream.writeAll(str); |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | | /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. |
| 538 | | pub fn cmpAbs(a: Int, b: Int) i8 { |
| 537 | /// Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| == |
| 538 | /// |b| or |a| > |b| respectively. |
| 539 | pub fn cmpAbs(a: Int, b: Int) math.Order { |
| 539 | 540 | if (a.len() < b.len()) { |
| 540 | | return -1; |
| 541 | return .lt; |
| 541 | 542 | } |
| 542 | 543 | if (a.len() > b.len()) { |
| 543 | | return 1; |
| 544 | return .gt; |
| 544 | 545 | } |
| 545 | 546 | |
| 546 | 547 | var i: usize = a.len() - 1; |
| ... | ... | @@ -551,21 +552,26 @@ pub const Int = struct { |
| 551 | 552 | } |
| 552 | 553 | |
| 553 | 554 | if (a.limbs[i] < b.limbs[i]) { |
| 554 | | return -1; |
| 555 | return .lt; |
| 555 | 556 | } else if (a.limbs[i] > b.limbs[i]) { |
| 556 | | return 1; |
| 557 | return .gt; |
| 557 | 558 | } else { |
| 558 | | return 0; |
| 559 | return .eq; |
| 559 | 560 | } |
| 560 | 561 | } |
| 561 | 562 | |
| 562 | | /// Returns -1, 0, 1 if a < b, a == b or a > b respectively. |
| 563 | | pub fn cmp(a: Int, b: Int) i8 { |
| 563 | /// Returns math.Order.lt, math.Order.eq, math.Order.gt if a < b, a == b or a |
| 564 | /// > b respectively. |
| 565 | pub fn cmp(a: Int, b: Int) math.Order { |
| 564 | 566 | if (a.isPositive() != b.isPositive()) { |
| 565 | | return if (a.isPositive()) @as(i8, 1) else -1; |
| 567 | return if (a.isPositive()) .gt else .lt; |
| 566 | 568 | } else { |
| 567 | 569 | const r = cmpAbs(a, b); |
| 568 | | return if (a.isPositive()) r else -r; |
| 570 | return if (a.isPositive()) r else switch (r) { |
| 571 | .lt => math.Order.gt, |
| 572 | .eq => math.Order.eq, |
| 573 | .gt => math.Order.lt, |
| 574 | }; |
| 569 | 575 | } |
| 570 | 576 | } |
| 571 | 577 | |
| ... | ... | @@ -576,12 +582,12 @@ pub const Int = struct { |
| 576 | 582 | |
| 577 | 583 | /// Returns true if |a| == |b|. |
| 578 | 584 | pub fn eqAbs(a: Int, b: Int) bool { |
| 579 | | return cmpAbs(a, b) == 0; |
| 585 | return cmpAbs(a, b) == .eq; |
| 580 | 586 | } |
| 581 | 587 | |
| 582 | 588 | /// Returns true if a == b. |
| 583 | 589 | pub fn eq(a: Int, b: Int) bool { |
| 584 | | return cmp(a, b) == 0; |
| 590 | return cmp(a, b) == .eq; |
| 585 | 591 | } |
| 586 | 592 | |
| 587 | 593 | // Normalize a possible sequence of leading zeros. |
| ... | ... | @@ -694,7 +700,7 @@ pub const Int = struct { |
| 694 | 700 | } else { |
| 695 | 701 | if (a.isPositive()) { |
| 696 | 702 | // (a) - (b) => a - b |
| 697 | | if (a.cmp(b) >= 0) { |
| 703 | if (a.cmp(b) != .lt) { |
| 698 | 704 | try r.ensureCapacity(a.len() + 1); |
| 699 | 705 | llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); |
| 700 | 706 | r.normalize(a.len()); |
| ... | ... | @@ -707,7 +713,7 @@ pub const Int = struct { |
| 707 | 713 | } |
| 708 | 714 | } else { |
| 709 | 715 | // (-a) - (-b) => -(a - b) |
| 710 | | if (a.cmp(b) < 0) { |
| 716 | if (a.cmp(b) == .lt) { |
| 711 | 717 | try r.ensureCapacity(a.len() + 1); |
| 712 | 718 | llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); |
| 713 | 719 | r.normalize(a.len()); |
| ... | ... | @@ -1010,7 +1016,7 @@ pub const Int = struct { |
| 1010 | 1016 | @panic("quo and rem cannot be same variable"); |
| 1011 | 1017 | } |
| 1012 | 1018 | |
| 1013 | | if (a.cmpAbs(b) < 0) { |
| 1019 | if (a.cmpAbs(b) == .lt) { |
| 1014 | 1020 | // quo may alias a so handle rem first |
| 1015 | 1021 | try rem.copy(a); |
| 1016 | 1022 | rem.setSign(a.isPositive() == b.isPositive()); |
| ... | ... | @@ -1133,7 +1139,7 @@ pub const Int = struct { |
| 1133 | 1139 | |
| 1134 | 1140 | // 2. |
| 1135 | 1141 | try tmp.shiftLeft(y.*, Limb.bit_count * (n - t)); |
| 1136 | | while (x.cmp(tmp) >= 0) { |
| 1142 | while (x.cmp(tmp) != .lt) { |
| 1137 | 1143 | q.limbs[n - t] += 1; |
| 1138 | 1144 | try x.sub(x.*, tmp); |
| 1139 | 1145 | } |
| ... | ... | @@ -1164,7 +1170,7 @@ pub const Int = struct { |
| 1164 | 1170 | r.limbs[2] = carry; |
| 1165 | 1171 | r.normalize(3); |
| 1166 | 1172 | |
| 1167 | | if (r.cmpAbs(tmp) <= 0) { |
| 1173 | if (r.cmpAbs(tmp) != .gt) { |
| 1168 | 1174 | break; |
| 1169 | 1175 | } |
| 1170 | 1176 | |
| ... | ... | @@ -1719,8 +1725,8 @@ test "big.int compare" { |
| 1719 | 1725 | var b = try Int.initSet(testing.allocator, 10); |
| 1720 | 1726 | defer b.deinit(); |
| 1721 | 1727 | |
| 1722 | | testing.expect(a.cmpAbs(b) == 1); |
| 1723 | | testing.expect(a.cmp(b) == -1); |
| 1728 | testing.expect(a.cmpAbs(b) == .gt); |
| 1729 | testing.expect(a.cmp(b) == .lt); |
| 1724 | 1730 | } |
| 1725 | 1731 | |
| 1726 | 1732 | test "big.int compare similar" { |
| ... | ... | @@ -1729,8 +1735,8 @@ test "big.int compare similar" { |
| 1729 | 1735 | var b = try Int.initSet(testing.allocator, 0xffffffffeeeeeeeeffffffffeeeeeeef); |
| 1730 | 1736 | defer b.deinit(); |
| 1731 | 1737 | |
| 1732 | | testing.expect(a.cmpAbs(b) == -1); |
| 1733 | | testing.expect(b.cmpAbs(a) == 1); |
| 1738 | testing.expect(a.cmpAbs(b) == .lt); |
| 1739 | testing.expect(b.cmpAbs(a) == .gt); |
| 1734 | 1740 | } |
| 1735 | 1741 | |
| 1736 | 1742 | test "big.int compare different limb size" { |
| ... | ... | @@ -1739,8 +1745,8 @@ test "big.int compare different limb size" { |
| 1739 | 1745 | var b = try Int.initSet(testing.allocator, 1); |
| 1740 | 1746 | defer b.deinit(); |
| 1741 | 1747 | |
| 1742 | | testing.expect(a.cmpAbs(b) == 1); |
| 1743 | | testing.expect(b.cmpAbs(a) == -1); |
| 1748 | testing.expect(a.cmpAbs(b) == .gt); |
| 1749 | testing.expect(b.cmpAbs(a) == .lt); |
| 1744 | 1750 | } |
| 1745 | 1751 | |
| 1746 | 1752 | test "big.int compare multi-limb" { |
| ... | ... | @@ -1749,8 +1755,8 @@ test "big.int compare multi-limb" { |
| 1749 | 1755 | var b = try Int.initSet(testing.allocator, 0x7777777799999999ffffeeeeffffeeeeffffeeeee); |
| 1750 | 1756 | defer b.deinit(); |
| 1751 | 1757 | |
| 1752 | | testing.expect(a.cmpAbs(b) == 1); |
| 1753 | | testing.expect(a.cmp(b) == -1); |
| 1758 | testing.expect(a.cmpAbs(b) == .gt); |
| 1759 | testing.expect(a.cmp(b) == .lt); |
| 1754 | 1760 | } |
| 1755 | 1761 | |
| 1756 | 1762 | test "big.int equality" { |
| ... | ... | @@ -2726,9 +2732,9 @@ test "big.int var args" { |
| 2726 | 2732 | |
| 2727 | 2733 | const c = try Int.initSet(testing.allocator, 11); |
| 2728 | 2734 | defer c.deinit(); |
| 2729 | | testing.expect(a.cmp(c) == 0); |
| 2735 | testing.expect(a.cmp(c) == .eq); |
| 2730 | 2736 | |
| 2731 | 2737 | const d = try Int.initSet(testing.allocator, 14); |
| 2732 | 2738 | defer d.deinit(); |
| 2733 | | testing.expect(a.cmp(d) <= 0); |
| 2739 | testing.expect(a.cmp(d) != .gt); |
| 2734 | 2740 | } |