start fixing after rebase
This commit is contained in:
parent
c305e5be60
commit
0c148e7207
@ -57,3 +57,4 @@ version = "1.0"
|
||||
default = ["std"]
|
||||
i128 = ["num-integer/i128", "num-traits/i128"]
|
||||
std = ["num-integer/std", "num-traits/std"]
|
||||
u64_digit = []
|
194
src/biguint.rs
194
src/biguint.rs
@ -561,6 +561,7 @@ impl Add<u64> for BigUint {
|
||||
}
|
||||
|
||||
impl AddAssign<u64> for BigUint {
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: u64) {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
@ -577,6 +578,21 @@ impl AddAssign<u64> for BigUint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: u64) {
|
||||
if other != 0 {
|
||||
if self.data.len() == 0 {
|
||||
self.data.push(0);
|
||||
}
|
||||
|
||||
let carry = __add2(&mut self.data, &[other as BigDigit]);
|
||||
if carry != 0 {
|
||||
self.data.push(carry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_i128)]
|
||||
@ -592,6 +608,7 @@ impl Add<u128> for BigUint {
|
||||
|
||||
#[cfg(has_i128)]
|
||||
impl AddAssign<u128> for BigUint {
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: u128) {
|
||||
if other <= u64::max_value() as u128 {
|
||||
@ -616,6 +633,24 @@ impl AddAssign<u128> for BigUint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: u128) {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
if hi == 0 {
|
||||
*self += lo;
|
||||
} else {
|
||||
while self.data.len() < 2 {
|
||||
self.data.push(0);
|
||||
}
|
||||
|
||||
let carry = __add2(&mut self.data, &[lo, hi]);
|
||||
if carry != 0 {
|
||||
self.data.push(carry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forward_val_val_binop!(impl Sub for BigUint, sub);
|
||||
@ -681,19 +716,18 @@ impl SubAssign<u32> for BigUint {
|
||||
impl Sub<BigUint> for u32 {
|
||||
type Output = BigUint;
|
||||
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn sub(self, mut other: BigUint) -> BigUint {
|
||||
while other.data.len() < 2 {
|
||||
other.data.push(0);
|
||||
if other.data.len() == 0 {
|
||||
other.data.push(self);
|
||||
} else {
|
||||
sub2rev(&[self], &mut other.data[..]);
|
||||
}
|
||||
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(self);
|
||||
sub2rev(&[lo, hi], &mut other.data[..]);
|
||||
other.normalized()
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn sub(self, mut other: BigUint) -> BigUint {
|
||||
if other.data.len() == 0 {
|
||||
@ -716,17 +750,26 @@ impl Sub<u64> for BigUint {
|
||||
}
|
||||
|
||||
impl SubAssign<u64> for BigUint {
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: u64) {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
sub2(&mut self.data[..], &[lo, hi]);
|
||||
self.normalize();
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: u64) {
|
||||
sub2(&mut self.data[..], &[other as BigDigit]);
|
||||
self.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<BigUint> for u64 {
|
||||
type Output = BigUint;
|
||||
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn sub(self, mut other: BigUint) -> BigUint {
|
||||
while other.data.len() < 2 {
|
||||
@ -737,6 +780,17 @@ impl Sub<BigUint> for u64 {
|
||||
sub2rev(&[lo, hi], &mut other.data[..]);
|
||||
other.normalized()
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn sub(self, mut other: BigUint) -> BigUint {
|
||||
if other.data.len() == 0 {
|
||||
other.data.push(self);
|
||||
} else {
|
||||
sub2rev(&[self], &mut other.data[..]);
|
||||
}
|
||||
other.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_i128)]
|
||||
@ -751,17 +805,28 @@ impl Sub<u128> for BigUint {
|
||||
}
|
||||
#[cfg(has_i128)]
|
||||
impl SubAssign<u128> for BigUint {
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: u128) {
|
||||
let (a, b, c, d) = u32_from_u128(other);
|
||||
sub2(&mut self.data[..], &[d, c, b, a]);
|
||||
self.normalize();
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: u128) {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
sub2(&mut self.data[..], &[lo, hi]);
|
||||
self.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_i128)]
|
||||
impl Sub<BigUint> for u128 {
|
||||
type Output = BigUint;
|
||||
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn sub(self, mut other: BigUint) -> BigUint {
|
||||
while other.data.len() < 4 {
|
||||
@ -772,6 +837,18 @@ impl Sub<BigUint> for u128 {
|
||||
sub2rev(&[d, c, b, a], &mut other.data[..]);
|
||||
other.normalized()
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn sub(self, mut other: BigUint) -> BigUint {
|
||||
while other.data.len() < 2 {
|
||||
other.data.push(0);
|
||||
}
|
||||
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(self);
|
||||
sub2rev(&[lo, hi], &mut other.data[..]);
|
||||
other.normalized()
|
||||
}
|
||||
}
|
||||
|
||||
forward_all_binop_to_ref_ref!(impl Mul for BigUint, mul);
|
||||
@ -832,6 +909,7 @@ impl Mul<u64> for BigUint {
|
||||
}
|
||||
}
|
||||
impl MulAssign<u64> for BigUint {
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, other: u64) {
|
||||
if other == 0 {
|
||||
@ -843,29 +921,17 @@ impl MulAssign<u64> for BigUint {
|
||||
*self = mul3(&self.data[..], &[lo, hi])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
impl Mul<u128> for BigUint {
|
||||
type Output = BigUint;
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn mul(mut self, other: u128) -> BigUint {
|
||||
self *= other;
|
||||
self
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "i128")]
|
||||
impl MulAssign<u128> for BigUint {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, other: u128) {
|
||||
fn mul_assign(&mut self, other: u64) {
|
||||
if other == 0 {
|
||||
self.data.clear();
|
||||
} else if other <= BigDigit::max_value() as u128 {
|
||||
*self *= other
|
||||
} else {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
*self = mul3(&self.data[..], &[lo, hi])
|
||||
let carry = scalar_mul(&mut self.data[..], other as BigDigit);
|
||||
if carry != 0 {
|
||||
self.data.push(carry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -882,6 +948,7 @@ impl Mul<u128> for BigUint {
|
||||
}
|
||||
#[cfg(has_i128)]
|
||||
impl MulAssign<u128> for BigUint {
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, other: u128) {
|
||||
if other == 0 {
|
||||
@ -893,6 +960,19 @@ impl MulAssign<u128> for BigUint {
|
||||
*self = mul3(&self.data[..], &[d, c, b, a])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, other: u128) {
|
||||
if other == 0 {
|
||||
self.data.clear();
|
||||
} else if other <= BigDigit::max_value() as u128 {
|
||||
*self *= other
|
||||
} else {
|
||||
let (hi, lo) = big_digit::from_doublebigdigit(other);
|
||||
*self = mul3(&self.data[..], &[lo, hi])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forward_all_binop_to_ref_ref!(impl Div for BigUint, div);
|
||||
@ -969,7 +1049,7 @@ impl DivAssign<u64> for BigUint {
|
||||
impl Div<BigUint> for u64 {
|
||||
type Output = BigUint;
|
||||
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn div(self, other: BigUint) -> BigUint {
|
||||
match other.data.len() {
|
||||
@ -980,7 +1060,7 @@ impl Div<BigUint> for u64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn div(self, other: BigUint) -> BigUint {
|
||||
match other.data.len() {
|
||||
@ -991,39 +1071,6 @@ impl Div<BigUint> for u64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
impl Div<u128> for BigUint {
|
||||
type Output = BigUint;
|
||||
|
||||
#[inline]
|
||||
fn div(self, other: u128) -> BigUint {
|
||||
let (q, _) = self.div_rem(&From::from(other));
|
||||
q
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "i128")]
|
||||
impl DivAssign<u128> for BigUint {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, other: u128) {
|
||||
*self = &*self / other;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
impl Div<BigUint> for u128 {
|
||||
type Output = BigUint;
|
||||
|
||||
#[inline]
|
||||
fn div(self, other: BigUint) -> BigUint {
|
||||
match other.data.len() {
|
||||
0 => panic!(),
|
||||
1 => From::from(self / other.data[0] as u128),
|
||||
2 => From::from(self / big_digit::to_doublebigdigit(other.data[1], other.data[0])),
|
||||
_ => Zero::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_i128)]
|
||||
impl Div<u128> for BigUint {
|
||||
type Output = BigUint;
|
||||
@ -1034,6 +1081,7 @@ impl Div<u128> for BigUint {
|
||||
q
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_i128)]
|
||||
impl DivAssign<u128> for BigUint {
|
||||
#[inline]
|
||||
@ -1046,6 +1094,7 @@ impl DivAssign<u128> for BigUint {
|
||||
impl Div<BigUint> for u128 {
|
||||
type Output = BigUint;
|
||||
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn div(self, other: BigUint) -> BigUint {
|
||||
match other.data.len() {
|
||||
@ -1061,6 +1110,17 @@ impl Div<BigUint> for u128 {
|
||||
_ => Zero::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn div(self, other: BigUint) -> BigUint {
|
||||
match other.data.len() {
|
||||
0 => panic!(),
|
||||
1 => From::from(self / other.data[0] as u128),
|
||||
2 => From::from(self / big_digit::to_doublebigdigit(other.data[1], other.data[0])),
|
||||
_ => Zero::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forward_all_binop_to_ref_ref!(impl Rem for BigUint, rem);
|
||||
@ -1845,19 +1905,19 @@ pub fn to_str_radix_reversed(u: &BigUint, radix: u32) -> Vec<u8> {
|
||||
res
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
fn ensure_big_digit(raw: Vec<u32>) -> Vec<BigDigit> {
|
||||
raw
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn ensure_big_digit(raw: Vec<u32>) -> Vec<BigDigit> {
|
||||
ensure_big_digit_slice(&raw)
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
fn ensure_big_digit_slice(raw: &[u32]) -> Vec<BigDigit> {
|
||||
raw.chunks(2)
|
||||
@ -1908,12 +1968,12 @@ impl BigUint {
|
||||
/// Assign a value to a `BigUint`.
|
||||
///
|
||||
/// The digits are in little-endian base 2<sup>32</sup>.
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[inline]
|
||||
pub fn assign_from_slice(&mut self, slice: &[u32]) {
|
||||
self.assign_from_slice_native(slice);
|
||||
}
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[inline]
|
||||
pub fn assign_from_slice(&mut self, slice: &[u32]) {
|
||||
let slice_digits = ensure_big_digit_slice(slice);
|
||||
@ -2914,7 +2974,7 @@ fn get_radix_base(radix: u32) -> (BigDigit, usize) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
#[test]
|
||||
fn test_from_slice() {
|
||||
fn check(slice: &[u32], data: &[BigDigit]) {
|
||||
@ -2928,7 +2988,7 @@ fn test_from_slice() {
|
||||
check(&[-1i32 as u32], &[-1i32 as BigDigit]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
#[test]
|
||||
fn test_from_slice() {
|
||||
fn check(slice: &[u32], data: &[BigDigit]) {
|
||||
|
20
src/lib.rs
20
src/lib.rs
@ -167,33 +167,33 @@ pub use bigrand::{RandBigInt, RandomBits, UniformBigInt, UniformBigUint};
|
||||
|
||||
mod big_digit {
|
||||
/// A `BigDigit` is a `BigUint`'s composing element.
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
pub type BigDigit = u32;
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
pub type BigDigit = u64;
|
||||
|
||||
/// A `DoubleBigDigit` is the internal type used to do the computations. Its
|
||||
/// size is the double of the size of `BigDigit`.
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
pub type DoubleBigDigit = u64;
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
pub type DoubleBigDigit = u128;
|
||||
|
||||
/// A `SignedDoubleBigDigit` is the signed version of `DoubleBigDigit`.
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
pub type SignedDoubleBigDigit = i64;
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
pub type SignedDoubleBigDigit = i128;
|
||||
|
||||
// `DoubleBigDigit` size dependent
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
pub const BITS: usize = 32;
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
pub const BITS: usize = 64;
|
||||
|
||||
#[cfg(not(feature = "i128"))]
|
||||
#[cfg(not(feature = "u64_digit"))]
|
||||
const LO_MASK: DoubleBigDigit = (-1i32 as DoubleBigDigit) >> BITS;
|
||||
#[cfg(feature = "i128")]
|
||||
#[cfg(feature = "u64_digit")]
|
||||
const LO_MASK: DoubleBigDigit = (-1i64 as DoubleBigDigit) >> BITS;
|
||||
|
||||
#[inline]
|
||||
|
Loading…
x
Reference in New Issue
Block a user