Add scalar ops for all remaining integer types
This commit is contained in:
parent
fd87d87db3
commit
2a3cd41820
|
@ -23,7 +23,7 @@ use self::Sign::{Minus, NoSign, Plus};
|
||||||
|
|
||||||
use super::ParseBigIntError;
|
use super::ParseBigIntError;
|
||||||
use super::big_digit;
|
use super::big_digit;
|
||||||
use super::big_digit::BigDigit;
|
use super::big_digit::{BigDigit, DoubleBigDigit};
|
||||||
use biguint;
|
use biguint;
|
||||||
use biguint::to_str_radix_reversed;
|
use biguint::to_str_radix_reversed;
|
||||||
use biguint::BigUint;
|
use biguint::BigUint;
|
||||||
|
@ -307,6 +307,14 @@ fn i32_abs_as_u32(a: i32) -> u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A convenience method for getting the absolute value of an i64 in a u64.
|
||||||
|
fn i64_abs_as_u64(a: i64) -> u64 {
|
||||||
|
match a.checked_abs() {
|
||||||
|
Some(x) => x as u64,
|
||||||
|
None => a as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We want to forward to BigUint::add, but it's not clear how that will go until
|
// 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
|
// we compare both sign and magnitude. So we duplicate this body for every
|
||||||
// val/ref combination, deferring that decision to BigUint's own forwarding.
|
// val/ref combination, deferring that decision to BigUint's own forwarding.
|
||||||
|
@ -372,6 +380,7 @@ impl Add<BigInt> for BigInt {
|
||||||
|
|
||||||
promote_all_scalars!(impl Add for BigInt, add);
|
promote_all_scalars!(impl Add for BigInt, add);
|
||||||
forward_all_scalar_binop_to_val_val_commutative!(impl Add<BigDigit> for BigInt, add);
|
forward_all_scalar_binop_to_val_val_commutative!(impl Add<BigDigit> for BigInt, add);
|
||||||
|
forward_all_scalar_binop_to_val_val_commutative!(impl Add<DoubleBigDigit> for BigInt, add);
|
||||||
|
|
||||||
impl Add<BigDigit> for BigInt {
|
impl Add<BigDigit> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -391,7 +400,26 @@ impl Add<BigDigit> for BigInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add<DoubleBigDigit> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: DoubleBigDigit) -> BigInt {
|
||||||
|
match self.sign {
|
||||||
|
NoSign => From::from(other),
|
||||||
|
Plus => BigInt::from_biguint(Plus, self.data + other),
|
||||||
|
Minus =>
|
||||||
|
match self.data.cmp(&From::from(other)) {
|
||||||
|
Equal => Zero::zero(),
|
||||||
|
Less => BigInt::from_biguint(Plus, other - self.data),
|
||||||
|
Greater => BigInt::from_biguint(Minus, self.data - 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<i32> for BigInt, add);
|
||||||
|
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i64> for BigInt, add);
|
||||||
|
|
||||||
impl Add<i32> for BigInt {
|
impl Add<i32> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -406,6 +434,19 @@ impl Add<i32> for BigInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add<i64> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: i64) -> BigInt {
|
||||||
|
if other >= 0 {
|
||||||
|
self + other as u64
|
||||||
|
} else {
|
||||||
|
self - i64_abs_as_u64(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We want to forward to BigUint::sub, but it's not clear how that will go until
|
// We want to forward to BigUint::sub, but it's not clear how that will go until
|
||||||
// we compare both sign and magnitude. So we duplicate this body for every
|
// we compare both sign and magnitude. So we duplicate this body for every
|
||||||
// val/ref combination, deferring that decision to BigUint's own forwarding.
|
// val/ref combination, deferring that decision to BigUint's own forwarding.
|
||||||
|
@ -471,6 +512,7 @@ impl Sub<BigInt> for BigInt {
|
||||||
|
|
||||||
promote_all_scalars!(impl Sub for BigInt, sub);
|
promote_all_scalars!(impl Sub for BigInt, sub);
|
||||||
forward_all_scalar_binop_to_val_val!(impl Sub<BigDigit> for BigInt, sub);
|
forward_all_scalar_binop_to_val_val!(impl Sub<BigDigit> for BigInt, sub);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Sub<DoubleBigDigit> for BigInt, sub);
|
||||||
|
|
||||||
impl Sub<BigDigit> for BigInt {
|
impl Sub<BigDigit> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -499,7 +541,35 @@ impl Sub<BigInt> for BigDigit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sub<DoubleBigDigit> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: DoubleBigDigit) -> BigInt {
|
||||||
|
match self.sign {
|
||||||
|
NoSign => BigInt::from_biguint(Minus, From::from(other)),
|
||||||
|
Minus => BigInt::from_biguint(Minus, self.data + other),
|
||||||
|
Plus =>
|
||||||
|
match self.data.cmp(&From::from(other)) {
|
||||||
|
Equal => Zero::zero(),
|
||||||
|
Greater => BigInt::from_biguint(Plus, self.data - other),
|
||||||
|
Less => BigInt::from_biguint(Minus, other - self.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<BigInt> for DoubleBigDigit {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: BigInt) -> BigInt {
|
||||||
|
-(other - self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_scalar_binop_to_val_val!(impl Sub<i32> for BigInt, sub);
|
forward_all_scalar_binop_to_val_val!(impl Sub<i32> for BigInt, sub);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Sub<i64> for BigInt, sub);
|
||||||
|
|
||||||
impl Sub<i32> for BigInt {
|
impl Sub<i32> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -527,6 +597,32 @@ impl Sub<BigInt> for i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sub<i64> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: i64) -> BigInt {
|
||||||
|
if other >= 0 {
|
||||||
|
self - other as u64
|
||||||
|
} else {
|
||||||
|
self + i64_abs_as_u64(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<BigInt> for i64 {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: BigInt) -> BigInt {
|
||||||
|
if self >= 0 {
|
||||||
|
self as u64 - other
|
||||||
|
} else {
|
||||||
|
-other - i64_abs_as_u64(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_binop_to_ref_ref!(impl Mul for BigInt, mul);
|
forward_all_binop_to_ref_ref!(impl Mul for BigInt, mul);
|
||||||
|
|
||||||
impl<'a, 'b> Mul<&'b BigInt> for &'a BigInt {
|
impl<'a, 'b> Mul<&'b BigInt> for &'a BigInt {
|
||||||
|
@ -540,6 +636,7 @@ impl<'a, 'b> Mul<&'b BigInt> for &'a BigInt {
|
||||||
|
|
||||||
promote_all_scalars!(impl Mul for BigInt, mul);
|
promote_all_scalars!(impl Mul for BigInt, mul);
|
||||||
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<BigDigit> for BigInt, mul);
|
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<BigDigit> for BigInt, mul);
|
||||||
|
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<DoubleBigDigit> for BigInt, mul);
|
||||||
|
|
||||||
impl Mul<BigDigit> for BigInt {
|
impl Mul<BigDigit> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -550,7 +647,17 @@ impl Mul<BigDigit> for BigInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mul<DoubleBigDigit> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: DoubleBigDigit) -> BigInt {
|
||||||
|
BigInt::from_biguint(self.sign, self.data * other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i32> for BigInt, mul);
|
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i32> for BigInt, mul);
|
||||||
|
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i64> for BigInt, mul);
|
||||||
|
|
||||||
impl Mul<i32> for BigInt {
|
impl Mul<i32> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -565,6 +672,19 @@ impl Mul<i32> for BigInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mul<i64> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: i64) -> BigInt {
|
||||||
|
if other >= 0 {
|
||||||
|
self * other as u64
|
||||||
|
} else {
|
||||||
|
-(self * i64_abs_as_u64(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_binop_to_ref_ref!(impl Div for BigInt, div);
|
forward_all_binop_to_ref_ref!(impl Div for BigInt, div);
|
||||||
|
|
||||||
impl<'a, 'b> Div<&'b BigInt> for &'a BigInt {
|
impl<'a, 'b> Div<&'b BigInt> for &'a BigInt {
|
||||||
|
@ -579,6 +699,7 @@ impl<'a, 'b> Div<&'b BigInt> for &'a BigInt {
|
||||||
|
|
||||||
promote_all_scalars!(impl Div for BigInt, div);
|
promote_all_scalars!(impl Div for BigInt, div);
|
||||||
forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigInt, div);
|
forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigInt, div);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Div<DoubleBigDigit> for BigInt, div);
|
||||||
|
|
||||||
impl Div<BigDigit> for BigInt {
|
impl Div<BigDigit> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -598,7 +719,26 @@ impl Div<BigInt> for BigDigit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Div<DoubleBigDigit> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: DoubleBigDigit) -> BigInt {
|
||||||
|
BigInt::from_biguint(self.sign, self.data / other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<BigInt> for DoubleBigDigit {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: BigInt) -> BigInt {
|
||||||
|
BigInt::from_biguint(other.sign, self / other.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_scalar_binop_to_val_val!(impl Div<i32> for BigInt, div);
|
forward_all_scalar_binop_to_val_val!(impl Div<i32> for BigInt, div);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Div<i64> for BigInt, div);
|
||||||
|
|
||||||
impl Div<i32> for BigInt {
|
impl Div<i32> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -626,6 +766,32 @@ impl Div<BigInt> for i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Div<i64> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: i64) -> BigInt {
|
||||||
|
if other >= 0 {
|
||||||
|
self / other as u64
|
||||||
|
} else {
|
||||||
|
-(self / i64_abs_as_u64(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<BigInt> for i64 {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: BigInt) -> BigInt {
|
||||||
|
if self >= 0 {
|
||||||
|
self as u64 / other
|
||||||
|
} else {
|
||||||
|
-(i64_abs_as_u64(self) / other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
|
forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
|
||||||
|
|
||||||
impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
|
impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
|
||||||
|
@ -640,6 +806,7 @@ impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
|
||||||
|
|
||||||
promote_all_scalars!(impl Rem for BigInt, rem);
|
promote_all_scalars!(impl Rem for BigInt, rem);
|
||||||
forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigInt, rem);
|
forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigInt, rem);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Rem<DoubleBigDigit> for BigInt, rem);
|
||||||
|
|
||||||
impl Rem<BigDigit> for BigInt {
|
impl Rem<BigDigit> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -659,7 +826,26 @@ impl Rem<BigInt> for BigDigit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Rem<DoubleBigDigit> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, other: DoubleBigDigit) -> BigInt {
|
||||||
|
BigInt::from_biguint(self.sign, self.data % other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rem<BigInt> for DoubleBigDigit {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, other: BigInt) -> BigInt {
|
||||||
|
BigInt::from_biguint(Plus, self % other.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_scalar_binop_to_val_val!(impl Rem<i32> for BigInt, rem);
|
forward_all_scalar_binop_to_val_val!(impl Rem<i32> for BigInt, rem);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Rem<i64> for BigInt, rem);
|
||||||
|
|
||||||
impl Rem<i32> for BigInt {
|
impl Rem<i32> for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
@ -687,6 +873,32 @@ impl Rem<BigInt> for i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Rem<i64> for BigInt {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, other: i64) -> BigInt {
|
||||||
|
if other >= 0 {
|
||||||
|
self % other as u64
|
||||||
|
} else {
|
||||||
|
self % i64_abs_as_u64(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rem<BigInt> for i64 {
|
||||||
|
type Output = BigInt;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, other: BigInt) -> BigInt {
|
||||||
|
if self >= 0 {
|
||||||
|
self as u64 % other
|
||||||
|
} else {
|
||||||
|
-(i64_abs_as_u64(self) % other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Neg for BigInt {
|
impl Neg for BigInt {
|
||||||
type Output = BigInt;
|
type Output = BigInt;
|
||||||
|
|
||||||
|
|
|
@ -396,6 +396,7 @@ impl<'a> Add<&'a BigUint> for BigUint {
|
||||||
|
|
||||||
promote_unsigned_scalars!(impl Add for BigUint, add);
|
promote_unsigned_scalars!(impl Add for BigUint, add);
|
||||||
forward_all_scalar_binop_to_val_val_commutative!(impl Add<BigDigit> for BigUint, add);
|
forward_all_scalar_binop_to_val_val_commutative!(impl Add<BigDigit> for BigUint, add);
|
||||||
|
forward_all_scalar_binop_to_val_val_commutative!(impl Add<DoubleBigDigit> for BigUint, add);
|
||||||
|
|
||||||
impl Add<BigDigit> for BigUint {
|
impl Add<BigDigit> for BigUint {
|
||||||
type Output = BigUint;
|
type Output = BigUint;
|
||||||
|
@ -414,6 +415,27 @@ impl Add<BigDigit> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add<DoubleBigDigit> for BigUint {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(mut self, other: DoubleBigDigit) -> BigUint {
|
||||||
|
if self.data.len() == 0 && other != 0 {
|
||||||
|
self.data.push(0);
|
||||||
|
}
|
||||||
|
if self.data.len() == 1 && other > BigDigit::max_value() as DoubleBigDigit {
|
||||||
|
self.data.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (lo, hi) = big_digit::from_doublebigdigit(other);
|
||||||
|
let carry = __add2(&mut self.data, &[lo, hi]);
|
||||||
|
if carry != 0 {
|
||||||
|
self.data.push(carry);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_val_val_binop!(impl Sub for BigUint, sub);
|
forward_val_val_binop!(impl Sub for BigUint, sub);
|
||||||
forward_ref_ref_binop!(impl Sub for BigUint, sub);
|
forward_ref_ref_binop!(impl Sub for BigUint, sub);
|
||||||
|
|
||||||
|
@ -442,6 +464,7 @@ impl<'a> Sub<BigUint> for &'a BigUint {
|
||||||
|
|
||||||
promote_unsigned_scalars!(impl Sub for BigUint, sub);
|
promote_unsigned_scalars!(impl Sub for BigUint, sub);
|
||||||
forward_all_scalar_binop_to_val_val!(impl Sub<BigDigit> for BigUint, sub);
|
forward_all_scalar_binop_to_val_val!(impl Sub<BigDigit> for BigUint, sub);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Sub<DoubleBigDigit> for BigUint, sub);
|
||||||
|
|
||||||
impl Sub<BigDigit> for BigUint {
|
impl Sub<BigDigit> for BigUint {
|
||||||
type Output = BigUint;
|
type Output = BigUint;
|
||||||
|
@ -467,6 +490,32 @@ impl Sub<BigUint> for BigDigit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sub<DoubleBigDigit> for BigUint {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(mut self, other: DoubleBigDigit) -> BigUint {
|
||||||
|
let (lo, hi) = big_digit::from_doublebigdigit(other);
|
||||||
|
sub2(&mut self.data[..], &[lo, hi]);
|
||||||
|
self.normalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<BigUint> for DoubleBigDigit {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, mut other: BigUint) -> BigUint {
|
||||||
|
while other.data.len() < 2 {
|
||||||
|
other.data.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (lo, hi) = big_digit::from_doublebigdigit(self);
|
||||||
|
sub2rev(&[lo, hi], &mut other.data[..]);
|
||||||
|
other.normalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_binop_to_ref_ref!(impl Mul for BigUint, mul);
|
forward_all_binop_to_ref_ref!(impl Mul for BigUint, mul);
|
||||||
|
|
||||||
impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint {
|
impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint {
|
||||||
|
@ -480,6 +529,7 @@ impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint {
|
||||||
|
|
||||||
promote_unsigned_scalars!(impl Mul for BigUint, mul);
|
promote_unsigned_scalars!(impl Mul for BigUint, mul);
|
||||||
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<BigDigit> for BigUint, mul);
|
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<BigDigit> for BigUint, mul);
|
||||||
|
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<DoubleBigDigit> for BigUint, mul);
|
||||||
|
|
||||||
impl Mul<BigDigit> for BigUint {
|
impl Mul<BigDigit> for BigUint {
|
||||||
type Output = BigUint;
|
type Output = BigUint;
|
||||||
|
@ -498,6 +548,23 @@ impl Mul<BigDigit> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mul<DoubleBigDigit> for BigUint {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(mut self, other: DoubleBigDigit) -> BigUint {
|
||||||
|
if other == 0 {
|
||||||
|
self.data.clear();
|
||||||
|
self
|
||||||
|
} else if other <= BigDigit::max_value() as DoubleBigDigit {
|
||||||
|
self * other as BigDigit
|
||||||
|
} else {
|
||||||
|
let (lo, hi) = big_digit::from_doublebigdigit(other);
|
||||||
|
mul3(&self.data[..], &[lo, hi])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
forward_all_binop_to_ref_ref!(impl Div for BigUint, div);
|
forward_all_binop_to_ref_ref!(impl Div for BigUint, div);
|
||||||
|
|
||||||
impl<'a, 'b> Div<&'b BigUint> for &'a BigUint {
|
impl<'a, 'b> Div<&'b BigUint> for &'a BigUint {
|
||||||
|
@ -512,6 +579,7 @@ impl<'a, 'b> Div<&'b BigUint> for &'a BigUint {
|
||||||
|
|
||||||
promote_unsigned_scalars!(impl Div for BigUint, div);
|
promote_unsigned_scalars!(impl Div for BigUint, div);
|
||||||
forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigUint, div);
|
forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigUint, div);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Div<DoubleBigDigit> for BigUint, div);
|
||||||
|
|
||||||
impl Div<BigDigit> for BigUint {
|
impl Div<BigDigit> for BigUint {
|
||||||
type Output = BigUint;
|
type Output = BigUint;
|
||||||
|
@ -531,7 +599,31 @@ impl Div<BigUint> for BigDigit {
|
||||||
match other.data.len() {
|
match other.data.len() {
|
||||||
0 => panic!(),
|
0 => panic!(),
|
||||||
1 => From::from(self / other.data[0]),
|
1 => From::from(self / other.data[0]),
|
||||||
_ => Zero::zero()
|
_ => Zero::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<DoubleBigDigit> for BigUint {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: DoubleBigDigit) -> BigUint {
|
||||||
|
let (q, _) = self.div_rem(&From::from(other));
|
||||||
|
q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<BigUint> for DoubleBigDigit {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, other: BigUint) -> BigUint {
|
||||||
|
match other.data.len() {
|
||||||
|
0 => panic!(),
|
||||||
|
1 => From::from(self / other.data[0] as u64),
|
||||||
|
2 => From::from(self / big_digit::to_doublebigdigit(other.data[0], other.data[1])),
|
||||||
|
_ => Zero::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,6 +642,7 @@ impl<'a, 'b> Rem<&'b BigUint> for &'a BigUint {
|
||||||
|
|
||||||
promote_unsigned_scalars!(impl Rem for BigUint, rem);
|
promote_unsigned_scalars!(impl Rem for BigUint, rem);
|
||||||
forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigUint, rem);
|
forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigUint, rem);
|
||||||
|
forward_all_scalar_binop_to_val_val!(impl Rem<DoubleBigDigit> for BigUint, rem);
|
||||||
|
|
||||||
impl Rem<BigDigit> for BigUint {
|
impl Rem<BigDigit> for BigUint {
|
||||||
type Output = BigUint;
|
type Output = BigUint;
|
||||||
|
@ -569,7 +662,31 @@ impl Rem<BigUint> for BigDigit {
|
||||||
match other.data.len() {
|
match other.data.len() {
|
||||||
0 => panic!(),
|
0 => panic!(),
|
||||||
1 => From::from(self % other.data[0]),
|
1 => From::from(self % other.data[0]),
|
||||||
_ => other
|
_ => From::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rem<DoubleBigDigit> for BigUint {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, other: DoubleBigDigit) -> BigUint {
|
||||||
|
let (_, r) = self.div_rem(&From::from(other));
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rem<BigUint> for DoubleBigDigit {
|
||||||
|
type Output = BigUint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rem(self, other: BigUint) -> BigUint {
|
||||||
|
match other.data.len() {
|
||||||
|
0 => panic!(),
|
||||||
|
1 => From::from(self % other.data[0] as u64),
|
||||||
|
2 => From::from(self % big_digit::to_doublebigdigit(other.data[0], other.data[1])),
|
||||||
|
_ => From::from(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,6 +219,13 @@ macro_rules! promote_unsigned_scalars_to_u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! promote_unsigned_scalars_to_u64 {
|
||||||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
promote_scalars!(impl $imp<u64> for $res, $method, usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! promote_signed_scalars_to_i32 {
|
macro_rules! promote_signed_scalars_to_i32 {
|
||||||
(impl $imp:ident for $res:ty, $method:ident) => {
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
@ -228,6 +235,13 @@ macro_rules! promote_signed_scalars_to_i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! promote_signed_scalars_to_i64 {
|
||||||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
promote_scalars!(impl $imp<i64> for $res, $method, isize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Forward everything to ref-ref, when reusing storage is not helpful
|
// Forward everything to ref-ref, when reusing storage is not helpful
|
||||||
macro_rules! forward_all_binop_to_ref_ref {
|
macro_rules! forward_all_binop_to_ref_ref {
|
||||||
(impl $imp:ident for $res:ty, $method:ident) => {
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
@ -273,12 +287,14 @@ macro_rules! forward_all_scalar_binop_to_val_val_commutative {
|
||||||
macro_rules! promote_unsigned_scalars {
|
macro_rules! promote_unsigned_scalars {
|
||||||
(impl $imp:ident for $res:ty, $method:ident) => {
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
promote_unsigned_scalars_to_u32!(impl $imp for $res, $method);
|
promote_unsigned_scalars_to_u32!(impl $imp for $res, $method);
|
||||||
|
promote_unsigned_scalars_to_u64!(impl $imp for $res, $method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! promote_signed_scalars {
|
macro_rules! promote_signed_scalars {
|
||||||
(impl $imp:ident for $res:ty, $method:ident) => {
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
promote_signed_scalars_to_i32!(impl $imp for $res, $method);
|
promote_signed_scalars_to_i32!(impl $imp for $res, $method);
|
||||||
|
promote_signed_scalars_to_i64!(impl $imp for $res, $method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue