use core::cmp::Ordering::{Equal, Greater, Less}; use core::iter::Sum; use core::mem; use core::ops::{Add, AddAssign}; use num_traits::CheckedAdd;
// We want to forward to BigUint::add, but it's not clear how that will go until // we compare both sign and magnitude. So we duplicate this body for every // val/ref combination, deferring that decision to BigUint's own forwarding.
macro_rules! bigint_add {
($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => { match ($a.sign, $b.sign) {
(_, NoSign) => $a_owned,
(NoSign, _) => $b_owned, // same sign => keep the sign with the sum of magnitudes
(Plus, Plus) | (Minus, Minus) => BigInt::from_biguint($a.sign, $a_data + $b_data), // opposite signs => keep the sign of the larger with the difference of magnitudes
(Plus, Minus) | (Minus, Plus) => match $a.data.cmp(&$b.data) {
Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
Equal => BigInt::ZERO,
},
}
};
}
impl Add<&BigInt> for &BigInt { type Output = BigInt;
impl AddAssign<&BigInt> for BigInt { #[inline] fn add_assign(&mutself, other: &BigInt) { let n = mem::replace(self, Self::ZERO);
*self = n + other;
}
}
forward_val_assign!(impl AddAssign for BigInt, add_assign);
promote_all_scalars!(impl Add for BigInt, add);
promote_all_scalars_assign!(impl AddAssign for BigInt, add_assign);
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u32> for BigInt, add);
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u64> for BigInt, add);
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u128> for BigInt, add);
impl AddAssign<u64> for BigInt { #[inline] fn add_assign(&mutself, other: u64) { let n = mem::replace(self, Self::ZERO);
*self = n + other;
}
}
impl Add<u128> for BigInt { type Output = BigInt;
#[inline] fn add(self, other: u128) -> BigInt { matchself.sign {
NoSign => BigInt::from(other),
Plus => BigInt::from(self.data + other),
Minus => matchself.data.cmp(&From::from(other)) {
Equal => Self::ZERO,
Less => BigInt::from(other - self.data),
Greater => -BigInt::from(self.data - other),
},
}
}
} impl AddAssign<u128> for BigInt { #[inline] fn add_assign(&mutself, other: u128) { let n = mem::replace(self, Self::ZERO);
*self = n + other;
}
}
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i32> for BigInt, add);
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i64> for BigInt, add);
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i128> for BigInt, add);
impl Add<i32> for BigInt { type Output = BigInt;
#[inline] fn add(self, other: i32) -> BigInt { match other.checked_uabs() {
Positive(u) => self + u,
Negative(u) => self - u,
}
}
} impl AddAssign<i32> for BigInt { #[inline] fn add_assign(&mutself, other: i32) { match other.checked_uabs() {
Positive(u) => *self += u,
Negative(u) => *self -= u,
}
}
}
impl Add<i64> for BigInt { type Output = BigInt;
#[inline] fn add(self, other: i64) -> BigInt { match other.checked_uabs() {
Positive(u) => self + u,
Negative(u) => self - u,
}
}
} impl AddAssign<i64> for BigInt { #[inline] fn add_assign(&mutself, other: i64) { match other.checked_uabs() {
Positive(u) => *self += u,
Negative(u) => *self -= u,
}
}
}
impl Add<i128> for BigInt { type Output = BigInt;
#[inline] fn add(self, other: i128) -> BigInt { match other.checked_uabs() {
Positive(u) => self + u,
Negative(u) => self - u,
}
}
} impl AddAssign<i128> for BigInt { #[inline] fn add_assign(&mutself, other: i128) { match other.checked_uabs() {
Positive(u) => *self += u,
Negative(u) => *self -= u,
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.