Merge rust-bitcoin/rust-bitcoin#2436: Add unchecked variants to Amount and SignedAmount
df1d2f6eb5
Add unchecked variants to Amount and SignedAmount (yancy) Pull request description: The checked variants have worse performance than the unchecked variants due to the additional branching operations. To improve performance where overflow is either not possible or not a concern, unchecked variants of `Amount` and `SignedAmount` are introduced for addition, subtraction and multiplication. Note, it seems the default behavior for the test framework is to panic on overflow, so I haven't figured out a good way to add tests for this. Marking as a draft for now. closes: https://github.com/rust-bitcoin/rust-bitcoin/issues/2434 ACKs for top commit: Kixunil: ACKdf1d2f6eb5
apoelstra: ACKdf1d2f6eb5
gonna go ahead and merge this, we can revisit if necessary when we look at `units` overflow behavior in general Tree-SHA512: 3fbb0ec81a758b350569226c44e25f6ca49e551566bee83c05c1c2b343874ef657d63a36b5f51c41582d8a8e36466275c574ebff6d363ed7c112ac8b4d5376fa
This commit is contained in:
commit
bf29a76d89
|
@ -864,6 +864,21 @@ impl Amount {
|
|||
/// Returns [None] if overflow occurred.
|
||||
pub fn checked_rem(self, rhs: u64) -> Option<Amount> { self.0.checked_rem(rhs).map(Amount) }
|
||||
|
||||
/// Unchecked addition.
|
||||
///
|
||||
///
|
||||
/// Computes `self + rhs`. Panics in debug mode, wraps in release mode.
|
||||
pub fn unchecked_add(self, rhs: Amount) -> Amount {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
|
||||
/// Unchecked subtraction.
|
||||
///
|
||||
/// Computes `self - rhs`. Panics in debug mode, wraps in release mode.
|
||||
pub fn unchecked_sub(self, rhs: Amount) -> Amount {
|
||||
Self(self.0 - rhs.0)
|
||||
}
|
||||
|
||||
/// Convert to a signed amount.
|
||||
pub fn to_signed(self) -> Result<SignedAmount, OutOfRangeError> {
|
||||
if self.to_sat() > SignedAmount::MAX.to_sat() as u64 {
|
||||
|
@ -1237,6 +1252,20 @@ impl SignedAmount {
|
|||
self.0.checked_rem(rhs).map(SignedAmount)
|
||||
}
|
||||
|
||||
/// Unchecked addition.
|
||||
///
|
||||
/// Computes `self + rhs`. Panics in debug mode, wraps in release mode.
|
||||
pub fn unchecked_add(self, rhs: SignedAmount) -> SignedAmount {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
|
||||
/// Unchecked subtraction.
|
||||
///
|
||||
/// Computes `self - rhs`. Panics in debug mode, wraps in release mode.
|
||||
pub fn unchecked_sub(self, rhs: SignedAmount) -> SignedAmount {
|
||||
Self(self.0 - rhs.0)
|
||||
}
|
||||
|
||||
/// Subtraction that doesn't allow negative [SignedAmount]s.
|
||||
/// Returns [None] if either [self], `rhs` or the result is strictly negative.
|
||||
pub fn positive_sub(self, rhs: SignedAmount) -> Option<SignedAmount> {
|
||||
|
@ -1934,6 +1963,34 @@ mod tests {
|
|||
assert_eq!(ssat(-6).checked_div(2), Some(ssat(-3)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn unchecked_amount_add() {
|
||||
let amt = Amount::MAX.unchecked_add(Amount::ONE_SAT);
|
||||
assert_eq!(amt, Amount::ZERO);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn unchecked_signed_amount_add() {
|
||||
let signed_amt = SignedAmount::MAX.unchecked_add(SignedAmount::ONE_SAT);
|
||||
assert_eq!(signed_amt, SignedAmount::MIN);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn unchecked_amount_subtract() {
|
||||
let amt = Amount::ZERO.unchecked_sub(Amount::ONE_SAT);
|
||||
assert_eq!(amt, Amount::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn unchecked_signed_amount_subtract() {
|
||||
let signed_amt = SignedAmount::MIN.unchecked_sub(SignedAmount::ONE_SAT);
|
||||
assert_eq!(signed_amt, SignedAmount::MAX);
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn floating_point() {
|
||||
|
|
Loading…
Reference in New Issue