Compare commits
2 Commits
cf262073dd
...
d6b0825b9a
Author | SHA1 | Date | |
---|---|---|---|
|
d6b0825b9a | ||
|
d90b762754 |
@ -6,15 +6,15 @@ use crate::num::*;
|
|||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
use alloc::vec::*;
|
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
|
||||||
use alloc::string::*;
|
use alloc::string::*;
|
||||||
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
|
use alloc::vec::*;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
use core::cmp::{Ordering, PartialOrd, PartialEq};
|
use core::cmp::{Ordering, PartialEq, PartialOrd};
|
||||||
use core::convert::TryInto;
|
use core::convert::*;
|
||||||
use core::mem::replace;
|
use core::mem::replace;
|
||||||
use core::ops::{
|
use core::ops::{
|
||||||
Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Sub, SubAssign,
|
Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Sub, SubAssign,
|
||||||
@ -465,7 +465,36 @@ macro_rules! impl_from_larger {
|
|||||||
impl From<$s> for BigInt {
|
impl From<$s> for BigInt {
|
||||||
/// Create a `BigInt` from a signed integer primitive
|
/// Create a `BigInt` from a signed integer primitive
|
||||||
fn from(n: $s) -> Self {
|
fn from(n: $s) -> Self {
|
||||||
todo!();
|
use core::usize::MAX;
|
||||||
|
let target_radix: $s = (MAX as $s) + 1;
|
||||||
|
let sign = if n < 0 { Sign::Negative } else { Sign::Positive };
|
||||||
|
let n = n.abs();
|
||||||
|
|
||||||
|
let mut quotient = n / target_radix;
|
||||||
|
let mut rem = n % target_radix;
|
||||||
|
|
||||||
|
if quotient == 0 {
|
||||||
|
Self::from(rem as usize)
|
||||||
|
} else {
|
||||||
|
let mut inner: Vec<usize> = Vec::new();
|
||||||
|
inner.push(rem as usize);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
rem = quotient % target_radix;
|
||||||
|
quotient = quotient / target_radix;
|
||||||
|
|
||||||
|
inner.push(rem as usize);
|
||||||
|
|
||||||
|
if (quotient == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt {
|
||||||
|
inner,
|
||||||
|
sign,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,14 +502,32 @@ macro_rules! impl_from_larger {
|
|||||||
/// Create a `BigInt` from an unsigned integer primitive
|
/// Create a `BigInt` from an unsigned integer primitive
|
||||||
fn from(n: $u) -> Self {
|
fn from(n: $u) -> Self {
|
||||||
use core::usize::MAX;
|
use core::usize::MAX;
|
||||||
|
let target_radix: $u = (MAX as $u) + 1;
|
||||||
|
|
||||||
let base_usize_value = n / MAX as $u;
|
let mut quotient = n / target_radix;
|
||||||
let rem = n % MAX as $u;
|
let mut rem = n % target_radix;
|
||||||
|
|
||||||
if base_usize_value == 0 {
|
if quotient == 0 {
|
||||||
Self::from(rem as usize)
|
Self::from(rem as usize)
|
||||||
} else {
|
} else {
|
||||||
todo!();
|
let mut inner: Vec<usize> = Vec::new();
|
||||||
|
inner.push(rem as usize);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
rem = quotient % target_radix;
|
||||||
|
quotient = quotient / target_radix;
|
||||||
|
|
||||||
|
inner.push(rem as usize);
|
||||||
|
|
||||||
|
if (quotient == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt {
|
||||||
|
inner,
|
||||||
|
sign: Sign::Positive
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,13 +576,16 @@ impl_from_larger!((i128, u128));
|
|||||||
impl_from_smaller!((i8, u8), (i16, u16), (i32, u32), (i64, u64));
|
impl_from_smaller!((i8, u8), (i16, u16), (i32, u32), (i64, u64));
|
||||||
|
|
||||||
// Implement PartialEq and PartialOrd to compare against BigInt values
|
// Implement PartialEq and PartialOrd to compare against BigInt values
|
||||||
impl_ord_literal!(i8,u8,i16,u16,i32,u32,i64,u64,i128,u128);
|
impl_ord_literal!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
const RADIX: u128 = core::usize::MAX as u128 + 1;
|
||||||
|
const I_RADIX: i128 = core::usize::MAX as i128 + 1;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity_checks() {
|
fn sanity_checks() {
|
||||||
let int = BigInt::from(45u8);
|
let int = BigInt::from(45u8);
|
||||||
@ -555,14 +605,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_trim_zeros() {
|
fn test_trim_zeros() {
|
||||||
let mut lotsoftrailing = BigInt {
|
let mut lots_of_leading = BigInt {
|
||||||
inner: vec![1, 0, 0, 0, 0, 0, 0, 0, 0],
|
inner: vec![1, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
sign: Positive,
|
sign: Positive,
|
||||||
};
|
};
|
||||||
|
|
||||||
lotsoftrailing.trim_zeros();
|
lots_of_leading.trim_zeros();
|
||||||
|
|
||||||
assert_eq!(BigInt::from(1), lotsoftrailing);
|
assert_eq!(BigInt::from(1), lots_of_leading);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -815,15 +865,23 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
|
||||||
fn test_from_large_unsigned() {
|
fn test_from_large_unsigned() {
|
||||||
BigInt::from(core::u128::MAX);
|
let big_num: u128 = 9 * RADIX + 8;
|
||||||
|
let res = BigInt::from(big_num);
|
||||||
|
|
||||||
|
assert_eq!(res.sign, Sign::Positive, "{:#?}", res);
|
||||||
|
assert_eq!(res.inner[0], 8usize, "{:#?}", res);
|
||||||
|
assert_eq!(res.inner[1], 9usize, "{:#?}", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
|
||||||
fn test_from_large_signed() {
|
fn test_from_large_signed() {
|
||||||
BigInt::from(128i128);
|
let big_num: i128 = 2 * I_RADIX + 3;
|
||||||
|
let res = BigInt::from(-big_num);
|
||||||
|
|
||||||
|
assert_eq!(res.sign, Sign::Negative, "{:#?}", res);
|
||||||
|
assert_eq!(res.inner[0], 3usize, "{:#?}", res);
|
||||||
|
assert_eq!(res.inner[1], 2usize, "{:#?}", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -65,7 +65,7 @@ impl PartialOrd for Sign {
|
|||||||
Self::Negative => match other {
|
Self::Negative => match other {
|
||||||
Self::Positive => Some(Ordering::Less),
|
Self::Positive => Some(Ordering::Less),
|
||||||
Self::Negative => Some(Ordering::Equal),
|
Self::Negative => Some(Ordering::Equal),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user