Skip to content

Commit

Permalink
bigint: add From implementations
Browse files Browse the repository at this point in the history
From all primative unsigned ints to BigUint
From all primative ints to BigInt
From BigUint to BigInt

Closes: rust-num#117
  • Loading branch information
ollie27 committed Dec 12, 2015
1 parent f2ea30d commit 8e1c6a3
Showing 1 changed file with 94 additions and 21 deletions.
115 changes: 94 additions & 21 deletions src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1105,27 +1105,47 @@ impl ToPrimitive for BigUint {
impl FromPrimitive for BigUint {
#[inline]
fn from_i64(n: i64) -> Option<BigUint> {
if n > 0 {
FromPrimitive::from_u64(n as u64)
} else if n == 0 {
Some(Zero::zero())
if n >= 0 {
Some(BigUint::from(n as u64))
} else {
None
}
}

// `DoubleBigDigit` size dependent
#[inline]
fn from_u64(n: u64) -> Option<BigUint> {
let n = match big_digit::from_doublebigdigit(n) {
(0, 0) => Zero::zero(),
(0, n0) => BigUint::new(vec!(n0)),
(n1, n0) => BigUint::new(vec!(n0, n1))
};
Some(n)
Some(BigUint::from(n))
}
}

impl From<u64> for BigUint {
// `DoubleBigDigit` size dependent
#[inline]
fn from(n: u64) -> Self {
match big_digit::from_doublebigdigit(n) {
(0, 0) => BigUint::zero(),
(0, n0) => BigUint { data: vec![n0] },
(n1, n0) => BigUint { data: vec![n0, n1] },
}
}
}

macro_rules! impl_biguint_from_uint {
($T:ty) => {
impl From<$T> for BigUint {
#[inline]
fn from(n: $T) -> Self {
BigUint::from(n as u64)
}
}
}
}

impl_biguint_from_uint!(u8);
impl_biguint_from_uint!(u16);
impl_biguint_from_uint!(u32);
impl_biguint_from_uint!(usize);

/// A generic trait for converting a value to a `BigUint`.
pub trait ToBigUint {
/// Converts the value of `self` to a `BigUint`.
Expand Down Expand Up @@ -1973,24 +1993,77 @@ impl ToPrimitive for BigInt {
impl FromPrimitive for BigInt {
#[inline]
fn from_i64(n: i64) -> Option<BigInt> {
Some(BigInt::from(n))
}

#[inline]
fn from_u64(n: u64) -> Option<BigInt> {
Some(BigInt::from(n))
}
}

impl From<i64> for BigInt {
#[inline]
fn from(n: i64) -> Self {
if n >= 0 {
FromPrimitive::from_u64(n as u64)
BigInt::from(n as u64)
} else {
let u = u64::MAX - (n as u64) + 1;
FromPrimitive::from_u64(u).map(|n| {
BigInt::from_biguint(Minus, n)
})
BigInt { sign: Minus, data: BigUint::from(u) }
}
}
}

macro_rules! impl_bigint_from_int {
($T:ty) => {
impl From<$T> for BigInt {
#[inline]
fn from(n: $T) -> Self {
BigInt::from(n as i64)
}
}
}
}

impl_bigint_from_int!(i8);
impl_bigint_from_int!(i16);
impl_bigint_from_int!(i32);
impl_bigint_from_int!(isize);

impl From<u64> for BigInt {
#[inline]
fn from_u64(n: u64) -> Option<BigInt> {
if n == 0 {
Some(Zero::zero())
fn from(n: u64) -> Self {
if n > 0 {
BigInt { sign: Plus, data: BigUint::from(n) }
} else {
BigInt::zero()
}
}
}

macro_rules! impl_bigint_from_uint {
($T:ty) => {
impl From<$T> for BigInt {
#[inline]
fn from(n: $T) -> Self {
BigInt::from(n as u64)
}
}
}
}

impl_bigint_from_uint!(u8);
impl_bigint_from_uint!(u16);
impl_bigint_from_uint!(u32);
impl_bigint_from_uint!(usize);

impl From<BigUint> for BigInt {
#[inline]
fn from(n: BigUint) -> Self {
if n.is_zero() {
BigInt::zero()
} else {
FromPrimitive::from_u64(n).map(|n| {
BigInt::from_biguint(Plus, n)
})
BigInt { sign: Plus, data: n }
}
}
}
Expand Down

0 comments on commit 8e1c6a3

Please sign in to comment.