From 8e1c6a3c11db42a1df825d65ac05b7156ac0d5eb Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 6 Dec 2015 21:22:12 +0000 Subject: [PATCH] bigint: add From implementations From all primative unsigned ints to BigUint From all primative ints to BigInt From BigUint to BigInt Closes: #117 --- src/bigint.rs | 121 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 24 deletions(-) diff --git a/src/bigint.rs b/src/bigint.rs index ebf4576..6ec9afa 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -1105,27 +1105,47 @@ impl ToPrimitive for BigUint { impl FromPrimitive for BigUint { #[inline] fn from_i64(n: i64) -> Option { - 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 { - 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 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`. @@ -1973,24 +1993,77 @@ impl ToPrimitive for BigInt { impl FromPrimitive for BigInt { #[inline] fn from_i64(n: i64) -> Option { - if n >= 0 { - FromPrimitive::from_u64(n as u64) - } else { - let u = u64::MAX - (n as u64) + 1; - FromPrimitive::from_u64(u).map(|n| { - BigInt::from_biguint(Minus, n) - }) - } + Some(BigInt::from(n)) } #[inline] fn from_u64(n: u64) -> Option { - if n == 0 { - Some(Zero::zero()) + Some(BigInt::from(n)) + } +} + +impl From for BigInt { + #[inline] + fn from(n: i64) -> Self { + if n >= 0 { + BigInt::from(n as u64) } else { - FromPrimitive::from_u64(n).map(|n| { - BigInt::from_biguint(Plus, n) - }) + let u = u64::MAX - (n as u64) + 1; + 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 for BigInt { + #[inline] + 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 for BigInt { + #[inline] + fn from(n: BigUint) -> Self { + if n.is_zero() { + BigInt::zero() + } else { + BigInt { sign: Plus, data: n } } } }