authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-01 20:57:10+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-04 11:25:29+02:00
log8701d8579dafc73856473ad5db73f3d5b4facc56
tree6c0f1476ce982cd6eca6fe87c367f450969b08af
parent96f095987f2f3a4d1be941b89afae0a706aad856

Adapt Value.intAddSat and intSubSat to new big int saturating functions


1 files changed, 34 insertions(+), 23 deletions(-)

src/value.zig+34-23
...@@ -1669,7 +1669,7 @@ pub const Value = extern union {...@@ -1669,7 +1669,7 @@ pub const Value = extern union {
1669 const rhs_bigint = rhs.toBigInt(&rhs_space);1669 const rhs_bigint = rhs.toBigInt(&rhs_space);
1670 const limbs = try arena.alloc(1670 const limbs = try arena.alloc(
1671 std.math.big.Limb,1671 std.math.big.Limb,
1672 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,1672 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
1673 );1673 );
1674 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1674 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1675 result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);1675 result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
...@@ -1693,19 +1693,25 @@ pub const Value = extern union {...@@ -1693,19 +1693,25 @@ pub const Value = extern union {
1693 assert(!lhs.isUndef());1693 assert(!lhs.isUndef());
1694 assert(!rhs.isUndef());1694 assert(!rhs.isUndef());
16951695
1696 const result = try intAdd(lhs, rhs, arena);1696 const info = ty.intInfo(target);
16971697
1698 const max = try ty.maxInt(arena, target);1698 var lhs_space: Value.BigIntSpace = undefined;
1699 if (compare(result, .gt, max, ty)) {1699 var rhs_space: Value.BigIntSpace = undefined;
1700 return max;1700 const lhs_bigint = lhs.toBigInt(&lhs_space);
1701 }1701 const rhs_bigint = rhs.toBigInt(&rhs_space);
1702 const limbs = try arena.alloc(
1703 std.math.big.Limb,
1704 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
1705 );
1706 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1707 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
1708 const result_limbs = result_bigint.limbs[0..result_bigint.len];
17021709
1703 const min = try ty.minInt(arena, target);1710 if (result_bigint.positive) {
1704 if (compare(result, .lt, min, ty)) {1711 return Value.Tag.int_big_positive.create(arena, result_limbs);
1705 return min;1712 } else {
1713 return Value.Tag.int_big_negative.create(arena, result_limbs);
1706 }1714 }
1707
1708 return result;
1709 }1715 }
17101716
1711 /// Supports both floats and ints; handles undefined.1717 /// Supports both floats and ints; handles undefined.
...@@ -1730,7 +1736,7 @@ pub const Value = extern union {...@@ -1730,7 +1736,7 @@ pub const Value = extern union {
1730 const rhs_bigint = rhs.toBigInt(&rhs_space);1736 const rhs_bigint = rhs.toBigInt(&rhs_space);
1731 const limbs = try arena.alloc(1737 const limbs = try arena.alloc(
1732 std.math.big.Limb,1738 std.math.big.Limb,
1733 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,1739 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
1734 );1740 );
1735 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1741 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1736 result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);1742 result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
...@@ -1741,7 +1747,6 @@ pub const Value = extern union {...@@ -1741,7 +1747,6 @@ pub const Value = extern union {
1741 } else {1747 } else {
1742 return Value.Tag.int_big_negative.create(arena, result_limbs);1748 return Value.Tag.int_big_negative.create(arena, result_limbs);
1743 }1749 }
1744
1745 }1750 }
17461751
1747 /// Supports integers only; asserts neither operand is undefined.1752 /// Supports integers only; asserts neither operand is undefined.
...@@ -1755,19 +1760,25 @@ pub const Value = extern union {...@@ -1755,19 +1760,25 @@ pub const Value = extern union {
1755 assert(!lhs.isUndef());1760 assert(!lhs.isUndef());
1756 assert(!rhs.isUndef());1761 assert(!rhs.isUndef());
17571762
1758 const result = try intSub(lhs, rhs, arena);1763 const info = ty.intInfo(target);
17591764
1760 const max = try ty.maxInt(arena, target);1765 var lhs_space: Value.BigIntSpace = undefined;
1761 if (compare(result, .gt, max, ty)) {1766 var rhs_space: Value.BigIntSpace = undefined;
1762 return max;1767 const lhs_bigint = lhs.toBigInt(&lhs_space);
1763 }1768 const rhs_bigint = rhs.toBigInt(&rhs_space);
1769 const limbs = try arena.alloc(
1770 std.math.big.Limb,
1771 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
1772 );
1773 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1774 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
1775 const result_limbs = result_bigint.limbs[0..result_bigint.len];
17641776
1765 const min = try ty.minInt(arena, target);1777 if (result_bigint.positive) {
1766 if (compare(result, .lt, min, ty)) {1778 return Value.Tag.int_big_positive.create(arena, result_limbs);
1767 return min;1779 } else {
1780 return Value.Tag.int_big_negative.create(arena, result_limbs);
1768 }1781 }
1769
1770 return result;
1771 }1782 }
17721783
1773 /// Supports both floats and ints; handles undefined.1784 /// Supports both floats and ints; handles undefined.