Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove big_digit::* from the public API #38

Merged
merged 1 commit into from
May 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 3 additions & 44 deletions src/algorithms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,7 @@ use bigint::BigInt;
use bigint::Sign;
use bigint::Sign::{Minus, NoSign, Plus};

#[allow(non_snake_case)]
pub mod big_digit {
/// A `BigDigit` is a `BigUint`'s composing element.
pub type BigDigit = u32;

/// A `DoubleBigDigit` is the internal type used to do the computations. Its
/// size is the double of the size of `BigDigit`.
pub type DoubleBigDigit = u64;

/// A `SignedDoubleBigDigit` is the signed version of `DoubleBigDigit`.
pub type SignedDoubleBigDigit = i64;

pub const ZERO_BIG_DIGIT: BigDigit = 0;

// `DoubleBigDigit` size dependent
pub const BITS: usize = 32;

pub const BASE: DoubleBigDigit = 1 << BITS;
const LO_MASK: DoubleBigDigit = (-1i32 as DoubleBigDigit) >> BITS;

#[inline]
fn get_hi(n: DoubleBigDigit) -> BigDigit {
(n >> BITS) as BigDigit
}
#[inline]
fn get_lo(n: DoubleBigDigit) -> BigDigit {
(n & LO_MASK) as BigDigit
}

/// Split one `DoubleBigDigit` into two `BigDigit`s.
#[inline]
pub fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
(get_hi(n), get_lo(n))
}

/// Join two `BigDigit`s into one `DoubleBigDigit`
#[inline]
pub fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
(lo as DoubleBigDigit) | ((hi as DoubleBigDigit) << BITS)
}
}

use big_digit::{BigDigit, DoubleBigDigit, SignedDoubleBigDigit};
use big_digit::{self, BigDigit, DoubleBigDigit, SignedDoubleBigDigit};

// Generic functions for add/subtract/multiply with carry/borrow:

Expand Down Expand Up @@ -647,7 +605,8 @@ pub fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {

#[cfg(test)]
mod algorithm_tests {
use {BigDigit, BigUint, BigInt};
use big_digit::BigDigit;
use {BigUint, BigInt};
use Sign::Plus;
use traits::Num;

Expand Down
8 changes: 4 additions & 4 deletions src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use traits::{ToPrimitive, FromPrimitive, Num, CheckedAdd, CheckedSub,
use self::Sign::{Minus, NoSign, Plus};

use super::ParseBigIntError;
use super::big_digit::{self, BigDigit, DoubleBigDigit};
use big_digit::{self, BigDigit, DoubleBigDigit};
use biguint;
use biguint::to_str_radix_reversed;
use biguint::{BigUint, IntDigits};
Expand Down Expand Up @@ -1868,7 +1868,7 @@ impl BigInt {
///
/// The digits are in little-endian base 2<sup>32</sup>.
#[inline]
pub fn new(sign: Sign, digits: Vec<BigDigit>) -> BigInt {
pub fn new(sign: Sign, digits: Vec<u32>) -> BigInt {
BigInt::from_biguint(sign, BigUint::new(digits))
}

Expand All @@ -1891,13 +1891,13 @@ impl BigInt {

/// Creates and initializes a `BigInt`.
#[inline]
pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
pub fn from_slice(sign: Sign, slice: &[u32]) -> BigInt {
BigInt::from_biguint(sign, BigUint::from_slice(slice))
}

/// Reinitializes a `BigInt`.
#[inline]
pub fn assign_from_slice(&mut self, sign: Sign, slice: &[BigDigit]) {
pub fn assign_from_slice(&mut self, sign: Sign, slice: &[u32]) {
if sign == NoSign {
self.data.assign_from_slice(&[]);
self.sign = NoSign;
Expand Down
13 changes: 5 additions & 8 deletions src/biguint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ use integer::Integer;
use traits::{ToPrimitive, FromPrimitive, Float, Num, Unsigned, CheckedAdd, CheckedSub, CheckedMul,
CheckedDiv, Zero, One};

use big_digit::{self, BigDigit, DoubleBigDigit};

#[path = "algorithms.rs"]
mod algorithms;
#[path = "monty.rs"]
mod monty;
pub use self::algorithms::big_digit;
pub use self::big_digit::{BigDigit, DoubleBigDigit, ZERO_BIG_DIGIT};

use self::algorithms::{mac_with_carry, mul3, scalar_mul, div_rem, div_rem_digit};
use self::algorithms::{__add2, __sub2rev, add2, sub2, sub2rev};
Expand All @@ -39,9 +39,6 @@ use UsizePromotion;
use ParseBigIntError;

/// A big unsigned integer type.
///
/// A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
/// `(a + b * big_digit::BASE + c * big_digit::BASE^2)`.
#[derive(Clone, Debug, Hash)]
pub struct BigUint {
data: Vec<BigDigit>,
Expand Down Expand Up @@ -1379,23 +1376,23 @@ impl BigUint {
///
/// The digits are in little-endian base 2<sup>32</sup>.
#[inline]
pub fn new(digits: Vec<BigDigit>) -> BigUint {
pub fn new(digits: Vec<u32>) -> BigUint {
BigUint { data: digits }.normalized()
}

/// Creates and initializes a `BigUint`.
///
/// The digits are in little-endian base 2<sup>32</sup>.
#[inline]
pub fn from_slice(slice: &[BigDigit]) -> BigUint {
pub fn from_slice(slice: &[u32]) -> BigUint {
BigUint::new(slice.to_vec())
}

/// Assign a value to a `BigUint`.
///
/// The digits are in little-endian base 2<sup>32</sup>.
#[inline]
pub fn assign_from_slice(&mut self, slice: &[BigDigit]) {
pub fn assign_from_slice(&mut self, slice: &[u32]) {
self.data.resize(slice.len(), 0);
self.data.clone_from_slice(slice);
self.normalize();
Expand Down
40 changes: 38 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,46 @@ mod bigint;

pub use biguint::BigUint;
pub use biguint::ToBigUint;
pub use biguint::big_digit;
pub use biguint::big_digit::{BigDigit, DoubleBigDigit, ZERO_BIG_DIGIT};

pub use bigint::Sign;
pub use bigint::BigInt;
pub use bigint::ToBigInt;
pub use bigint::RandBigInt;

mod big_digit {
/// A `BigDigit` is a `BigUint`'s composing element.
pub type BigDigit = u32;

/// A `DoubleBigDigit` is the internal type used to do the computations. Its
/// size is the double of the size of `BigDigit`.
pub type DoubleBigDigit = u64;

/// A `SignedDoubleBigDigit` is the signed version of `DoubleBigDigit`.
pub type SignedDoubleBigDigit = i64;

// `DoubleBigDigit` size dependent
pub const BITS: usize = 32;

const LO_MASK: DoubleBigDigit = (-1i32 as DoubleBigDigit) >> BITS;

#[inline]
fn get_hi(n: DoubleBigDigit) -> BigDigit {
(n >> BITS) as BigDigit
}
#[inline]
fn get_lo(n: DoubleBigDigit) -> BigDigit {
(n & LO_MASK) as BigDigit
}

/// Split one `DoubleBigDigit` into two `BigDigit`s.
#[inline]
pub fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
(get_hi(n), get_lo(n))
}

/// Join two `BigDigit`s into one `DoubleBigDigit`
#[inline]
pub fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
(lo as DoubleBigDigit) | ((hi as DoubleBigDigit) << BITS)
}
}
22 changes: 11 additions & 11 deletions tests/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ extern crate num_integer;
extern crate num_traits;
extern crate rand;

use num_bigint::{BigDigit, BigUint, big_digit};
use num_bigint::BigUint;
use num_bigint::{BigInt, ToBigInt};
use num_bigint::Sign::{Minus, NoSign, Plus};

Expand Down Expand Up @@ -163,7 +163,7 @@ fn test_from_signed_bytes_be() {

#[test]
fn test_cmp() {
let vs: [&[BigDigit]; 4] = [&[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1]];
let vs: [&[u32]; 4] = [&[2 as u32], &[1, 1], &[2, 1], &[1, 1, 1]];
let mut nums = Vec::new();
for s in vs.iter().rev() {
nums.push(BigInt::from_slice(Minus, *s));
Expand Down Expand Up @@ -244,7 +244,7 @@ fn test_convert_i64() {
None);

assert_eq!(BigInt::from_biguint(Minus,
BigUint::new(vec![1, 0, 0, 1 << (big_digit::BITS - 1)]))
BigUint::new(vec![1, 0, 0, 1 << 31]))
.to_i64(),
None);

Expand Down Expand Up @@ -458,11 +458,11 @@ fn test_convert_from_uint() {
}
}

check!(u8, BigInt::from_slice(Plus, &[u8::MAX as BigDigit]));
check!(u16, BigInt::from_slice(Plus, &[u16::MAX as BigDigit]));
check!(u32, BigInt::from_slice(Plus, &[u32::MAX as BigDigit]));
check!(u8, BigInt::from_slice(Plus, &[u8::MAX as u32]));
check!(u16, BigInt::from_slice(Plus, &[u16::MAX as u32]));
check!(u32, BigInt::from_slice(Plus, &[u32::MAX]));
check!(u64,
BigInt::from_slice(Plus, &[u32::MAX as BigDigit, u32::MAX as BigDigit]));
BigInt::from_slice(Plus, &[u32::MAX, u32::MAX]));
check!(usize, BigInt::from(usize::MAX as u64));
}

Expand All @@ -482,16 +482,16 @@ fn test_convert_from_int() {

check!(i8,
BigInt::from_slice(Minus, &[1 << 7]),
BigInt::from_slice(Plus, &[i8::MAX as BigDigit]));
BigInt::from_slice(Plus, &[i8::MAX as u32]));
check!(i16,
BigInt::from_slice(Minus, &[1 << 15]),
BigInt::from_slice(Plus, &[i16::MAX as BigDigit]));
BigInt::from_slice(Plus, &[i16::MAX as u32]));
check!(i32,
BigInt::from_slice(Minus, &[1 << 31]),
BigInt::from_slice(Plus, &[i32::MAX as BigDigit]));
BigInt::from_slice(Plus, &[i32::MAX as u32]));
check!(i64,
BigInt::from_slice(Minus, &[0, 1 << 31]),
BigInt::from_slice(Plus, &[u32::MAX as BigDigit, i32::MAX as BigDigit]));
BigInt::from_slice(Plus, &[u32::MAX, i32::MAX as u32]));
check!(isize,
BigInt::from(isize::MIN as i64),
BigInt::from(isize::MAX as i64));
Expand Down
6 changes: 3 additions & 3 deletions tests/bigint_bitwise.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
extern crate num_bigint;
extern crate num_traits;

use num_bigint::{BigDigit, BigInt, Sign, ToBigInt};
use num_bigint::{BigInt, Sign, ToBigInt};
use num_traits::ToPrimitive;
use std::{i32, i64, u32};

enum ValueVec {
N,
P(&'static [BigDigit]),
M(&'static [BigDigit]),
P(&'static [u32]),
M(&'static [u32]),
}

use ValueVec::*;
Expand Down
6 changes: 3 additions & 3 deletions tests/bigint_scalar.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate num_bigint;
extern crate num_traits;

use num_bigint::{BigDigit, BigInt};
use num_bigint::BigInt;
use num_bigint::Sign::Plus;
use num_traits::{Zero, Signed, ToPrimitive};

Expand Down Expand Up @@ -88,7 +88,7 @@ fn test_scalar_mul() {

#[test]
fn test_scalar_div_rem() {
fn check_sub(a: &BigInt, b: BigDigit, ans_q: &BigInt, ans_r: &BigInt) {
fn check_sub(a: &BigInt, b: u32, ans_q: &BigInt, ans_r: &BigInt) {
let (q, r) = (a / b, a % b);
if !r.is_zero() {
assert_eq!(r.sign(), a.sign());
Expand All @@ -109,7 +109,7 @@ fn test_scalar_div_rem() {
}
}

fn check(a: &BigInt, b: BigDigit, q: &BigInt, r: &BigInt) {
fn check(a: &BigInt, b: u32, q: &BigInt, r: &BigInt) {
check_sub(a, b, q, r);
check_sub(&a.neg(), b, &q.neg(), &r.neg());
}
Expand Down
52 changes: 29 additions & 23 deletions tests/biguint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extern crate num_traits;
extern crate rand;

use num_integer::Integer;
use num_bigint::{BigDigit, BigUint, ToBigUint, big_digit};
use num_bigint::{BigUint, ToBigUint};
use num_bigint::{BigInt, ToBigInt};
use num_bigint::Sign::Plus;

Expand Down Expand Up @@ -146,19 +146,25 @@ fn test_hash() {
assert!(hash(&d) != hash(&e));
}

const BIT_TESTS: &'static [(&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit])] = &[// LEFT RIGHT AND OR XOR
(&[], &[], &[], &[], &[]),
(&[1, 0, 1], &[1, 1], &[1], &[1, 1, 1], &[0, 1, 1]),
(&[1, 0, 1], &[0, 1, 1], &[0, 0, 1], &[1, 1, 1], &[1, 1]),
(&[268, 482, 17],
&[964, 54],
&[260, 34],
&[972, 502, 17],
&[712, 468, 17])];
// LEFT, RIGHT, AND, OR, XOR
const BIT_TESTS: &'static [(
&'static [u32],
&'static [u32],
&'static [u32],
&'static [u32],
&'static [u32],
)] = &[
(&[], &[], &[], &[], &[]),
(&[1, 0, 1], &[1, 1], &[1], &[1, 1, 1], &[0, 1, 1]),
(&[1, 0, 1], &[0, 1, 1], &[0, 0, 1], &[1, 1, 1], &[1, 1]),
(
&[268, 482, 17],
&[964, 54],
&[260, 34],
&[972, 502, 17],
&[712, 468, 17],
),
];

#[test]
fn test_bitand() {
Expand Down Expand Up @@ -473,9 +479,9 @@ fn test_convert_i64() {
check(i64::MAX.to_biguint().unwrap(), i64::MAX);

check(BigUint::new(vec![]), 0);
check(BigUint::new(vec![1]), 1 << (0 * big_digit::BITS));
check(BigUint::new(vec![N1]), (1 << (1 * big_digit::BITS)) - 1);
check(BigUint::new(vec![0, 1]), 1 << (1 * big_digit::BITS));
check(BigUint::new(vec![1]), 1);
check(BigUint::new(vec![N1]), (1 << 32) - 1);
check(BigUint::new(vec![0, 1]), 1 << 32);
check(BigUint::new(vec![N1, N1 >> 1]), i64::MAX);

assert_eq!(i64::MIN.to_biguint(), None);
Expand All @@ -499,9 +505,9 @@ fn test_convert_u64() {
check(u64::MAX.to_biguint().unwrap(), u64::MAX);

check(BigUint::new(vec![]), 0);
check(BigUint::new(vec![1]), 1 << (0 * big_digit::BITS));
check(BigUint::new(vec![N1]), (1 << (1 * big_digit::BITS)) - 1);
check(BigUint::new(vec![0, 1]), 1 << (1 * big_digit::BITS));
check(BigUint::new(vec![1]), 1);
check(BigUint::new(vec![N1]), (1 << 32) - 1);
check(BigUint::new(vec![0, 1]), 1 << 32);
check(BigUint::new(vec![N1, N1]), u64::MAX);

assert_eq!(BigUint::new(vec![0, 0, 1]).to_u64(), None);
Expand Down Expand Up @@ -667,8 +673,8 @@ fn test_convert_from_uint() {
}
}

check!(u8, BigUint::from_slice(&[u8::MAX as BigDigit]));
check!(u16, BigUint::from_slice(&[u16::MAX as BigDigit]));
check!(u8, BigUint::from_slice(&[u8::MAX as u32]));
check!(u16, BigUint::from_slice(&[u16::MAX as u32]));
check!(u32, BigUint::from_slice(&[u32::MAX]));
check!(u64, BigUint::from_slice(&[u32::MAX, u32::MAX]));
check!(usize, BigUint::from(usize::MAX as u64));
Expand Down Expand Up @@ -915,7 +921,7 @@ fn test_is_even() {
}

fn to_str_pairs() -> Vec<(BigUint, Vec<(u32, String)>)> {
let bits = big_digit::BITS;
let bits = 32;
vec![(Zero::zero(),
vec![(2, "0".to_string()), (3, "0".to_string())]),
(BigUint::from_slice(&[0xff]),
Expand Down
Loading