@@ -1518,6 +1518,51 @@ macro_rules! int_impl {
1518
1518
(a as Self, b)
1519
1519
}
1520
1520
1521
+ /// Calculates `self + rhs + carry` without the ability to overflow.
1522
+ ///
1523
+ /// Performs "signed ternary addition" which takes in an extra bit to add, and may return an
1524
+ /// additional bit of overflow. This signed function is used only on the highest-ordered data,
1525
+ /// for which the signed overflow result indicates whether the big integer overflowed or not.
1526
+ ///
1527
+ /// # Examples
1528
+ ///
1529
+ /// Basic usage:
1530
+ ///
1531
+ /// ```
1532
+ /// #![feature(bigint_helper_methods)]
1533
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, false), (7, false));")]
1534
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, true), (8, false));")]
1535
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), (", stringify!($SelfT), "::MIN, true));")]
1536
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(0, true), (", stringify!($SelfT), "::MIN, true));")]
1537
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, true), (", stringify!($SelfT), "::MIN + 1, true));")]
1538
+ #[doc = concat!("assert_eq!(",
1539
+ stringify!($SelfT), "::MAX.carrying_add(", stringify!($SelfT), "::MAX, true), ",
1540
+ "(-1, true));"
1541
+ )]
1542
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.carrying_add(-1, true), (", stringify!($SelfT), "::MIN, false));")]
1543
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".carrying_add(", stringify!($SelfT), "::MAX, true), (", stringify!($SelfT), "::MIN, true));")]
1544
+ /// ```
1545
+ ///
1546
+ /// If `carry` is false, this method is equivalent to [`overflowing_add`](Self::overflowing_add):
1547
+ ///
1548
+ /// ```
1549
+ /// #![feature(bigint_helper_methods)]
1550
+ #[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".carrying_add(2, false), 5_", stringify!($SelfT), ".overflowing_add(2));")]
1551
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), ", stringify!($SelfT), "::MAX.overflowing_add(1));")]
1552
+ /// ```
1553
+ #[unstable(feature = "bigint_helper_methods", issue = "85532")]
1554
+ #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
1555
+ #[must_use = "this returns the result of the operation, \
1556
+ without modifying the original"]
1557
+ #[inline]
1558
+ pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
1559
+ // note: longer-term this should be done via an intrinsic.
1560
+ // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
1561
+ let (a, b) = self.overflowing_add(rhs);
1562
+ let (c, d) = a.overflowing_add(carry as $SelfT);
1563
+ (c, b != d)
1564
+ }
1565
+
1521
1566
/// Calculates `self` + `rhs` with an unsigned `rhs`
1522
1567
///
1523
1568
/// Returns a tuple of the addition along with a boolean indicating
@@ -1569,6 +1614,39 @@ macro_rules! int_impl {
1569
1614
(a as Self, b)
1570
1615
}
1571
1616
1617
+ /// Calculates `self - rhs - borrow` without the ability to overflow.
1618
+ ///
1619
+ /// Performs "signed ternary subtraction" which takes in an extra bit to subtract, and may return an
1620
+ /// additional bit of overflow. This signed function is used only on the highest-ordered data,
1621
+ /// for which the signed overflow result indicates whether the big integer overflowed or not.
1622
+ ///
1623
+ /// # Examples
1624
+ ///
1625
+ /// Basic usage:
1626
+ ///
1627
+ /// ```
1628
+ /// #![feature(bigint_helper_methods)]
1629
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, false), (3, false));")]
1630
+ #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, true), (2, false));")]
1631
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, false), (-1, false));")]
1632
+ #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".borrowing_sub(1, true), (-2, false));")]
1633
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.borrowing_sub(1, true), (", stringify!($SelfT), "::MAX - 1, true));")]
1634
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.borrowing_sub(-1, false), (", stringify!($SelfT), "::MIN, true));")]
1635
+ #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.borrowing_sub(-1, true), (", stringify!($SelfT), "::MAX, false));")]
1636
+ /// ```
1637
+ #[unstable(feature = "bigint_helper_methods", issue = "85532")]
1638
+ #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
1639
+ #[must_use = "this returns the result of the operation, \
1640
+ without modifying the original"]
1641
+ #[inline]
1642
+ pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
1643
+ // note: longer-term this should be done via an intrinsic.
1644
+ // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
1645
+ let (a, b) = self.overflowing_sub(rhs);
1646
+ let (c, d) = a.overflowing_sub(borrow as $SelfT);
1647
+ (c, b != d)
1648
+ }
1649
+
1572
1650
/// Calculates `self` - `rhs` with an unsigned `rhs`
1573
1651
///
1574
1652
/// Returns a tuple of the subtraction along with a boolean indicating
0 commit comments