1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306 |
- use std::default::Default;
- use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Not};
- use std::str::{self, FromStr};
- use std::fmt;
- use std::cmp::Ordering::{self, Less, Greater, Equal};
- use std::{i64, u64};
- use std::ascii::AsciiExt;
- #[cfg(feature = "serde")]
- use serde;
- // Some of the tests of non-RNG-based functionality are randomized using the
- // RNG-based functionality, so the RNG-based functionality needs to be enabled
- // for tests.
- #[cfg(any(feature = "rand", test))]
- use rand::Rng;
- use integer::Integer;
- use traits::{ToPrimitive, FromPrimitive, Num, CheckedAdd, CheckedSub,
- CheckedMul, CheckedDiv, Signed, Zero, One};
- use self::Sign::{Minus, NoSign, Plus};
- use super::ParseBigIntError;
- use super::big_digit;
- use super::big_digit::BigDigit;
- use biguint;
- use biguint::to_str_radix_reversed;
- use biguint::BigUint;
- #[cfg(test)]
- #[path = "tests/bigint.rs"]
- mod bigint_tests;
- /// A Sign is a `BigInt`'s composing element.
- #[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, Hash)]
- #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
- pub enum Sign {
- Minus,
- NoSign,
- Plus,
- }
- impl Neg for Sign {
- type Output = Sign;
- /// Negate Sign value.
- #[inline]
- fn neg(self) -> Sign {
- match self {
- Minus => Plus,
- NoSign => NoSign,
- Plus => Minus,
- }
- }
- }
- impl Mul<Sign> for Sign {
- type Output = Sign;
- #[inline]
- fn mul(self, other: Sign) -> Sign {
- match (self, other) {
- (NoSign, _) | (_, NoSign) => NoSign,
- (Plus, Plus) | (Minus, Minus) => Plus,
- (Plus, Minus) | (Minus, Plus) => Minus,
- }
- }
- }
- #[cfg(feature = "serde")]
- impl serde::Serialize for Sign {
- fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
- where S: serde::Serializer
- {
- match *self {
- Sign::Minus => (-1i8).serialize(serializer),
- Sign::NoSign => 0i8.serialize(serializer),
- Sign::Plus => 1i8.serialize(serializer),
- }
- }
- }
- #[cfg(feature = "serde")]
- impl serde::Deserialize for Sign {
- fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
- where D: serde::Deserializer
- {
- use serde::de::Error;
- let sign: i8 = try!(serde::Deserialize::deserialize(deserializer));
- match sign {
- -1 => Ok(Sign::Minus),
- 0 => Ok(Sign::NoSign),
- 1 => Ok(Sign::Plus),
- _ => Err(D::Error::invalid_value("sign must be -1, 0, or 1")),
- }
- }
- }
- /// A big signed integer type.
- #[derive(Clone, Debug, Hash)]
- #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
- pub struct BigInt {
- sign: Sign,
- data: BigUint,
- }
- impl PartialEq for BigInt {
- #[inline]
- fn eq(&self, other: &BigInt) -> bool {
- self.cmp(other) == Equal
- }
- }
- impl Eq for BigInt {}
- impl PartialOrd for BigInt {
- #[inline]
- fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> {
- Some(self.cmp(other))
- }
- }
- impl Ord for BigInt {
- #[inline]
- fn cmp(&self, other: &BigInt) -> Ordering {
- let scmp = self.sign.cmp(&other.sign);
- if scmp != Equal {
- return scmp;
- }
- match self.sign {
- NoSign => Equal,
- Plus => self.data.cmp(&other.data),
- Minus => other.data.cmp(&self.data),
- }
- }
- }
- impl Default for BigInt {
- #[inline]
- fn default() -> BigInt {
- Zero::zero()
- }
- }
- impl fmt::Display for BigInt {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad_integral(!self.is_negative(), "", &self.data.to_str_radix(10))
- }
- }
- impl fmt::Binary for BigInt {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad_integral(!self.is_negative(), "0b", &self.data.to_str_radix(2))
- }
- }
- impl fmt::Octal for BigInt {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad_integral(!self.is_negative(), "0o", &self.data.to_str_radix(8))
- }
- }
- impl fmt::LowerHex for BigInt {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad_integral(!self.is_negative(), "0x", &self.data.to_str_radix(16))
- }
- }
- impl fmt::UpperHex for BigInt {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad_integral(!self.is_negative(),
- "0x",
- &self.data.to_str_radix(16).to_ascii_uppercase())
- }
- }
- impl FromStr for BigInt {
- type Err = ParseBigIntError;
- #[inline]
- fn from_str(s: &str) -> Result<BigInt, ParseBigIntError> {
- BigInt::from_str_radix(s, 10)
- }
- }
- impl Num for BigInt {
- type FromStrRadixErr = ParseBigIntError;
- /// Creates and initializes a BigInt.
- #[inline]
- fn from_str_radix(mut s: &str, radix: u32) -> Result<BigInt, ParseBigIntError> {
- let sign = if s.starts_with('-') {
- let tail = &s[1..];
- if !tail.starts_with('+') {
- s = tail
- }
- Minus
- } else {
- Plus
- };
- let bu = try!(BigUint::from_str_radix(s, radix));
- Ok(BigInt::from_biguint(sign, bu))
- }
- }
- impl Shl<usize> for BigInt {
- type Output = BigInt;
- #[inline]
- fn shl(self, rhs: usize) -> BigInt {
- (&self) << rhs
- }
- }
- impl<'a> Shl<usize> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn shl(self, rhs: usize) -> BigInt {
- BigInt::from_biguint(self.sign, &self.data << rhs)
- }
- }
- impl Shr<usize> for BigInt {
- type Output = BigInt;
- #[inline]
- fn shr(self, rhs: usize) -> BigInt {
- BigInt::from_biguint(self.sign, self.data >> rhs)
- }
- }
- impl<'a> Shr<usize> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn shr(self, rhs: usize) -> BigInt {
- BigInt::from_biguint(self.sign, &self.data >> rhs)
- }
- }
- impl Zero for BigInt {
- #[inline]
- fn zero() -> BigInt {
- BigInt::from_biguint(NoSign, Zero::zero())
- }
- #[inline]
- fn is_zero(&self) -> bool {
- self.sign == NoSign
- }
- }
- impl One for BigInt {
- #[inline]
- fn one() -> BigInt {
- BigInt::from_biguint(Plus, One::one())
- }
- }
- impl Signed for BigInt {
- #[inline]
- fn abs(&self) -> BigInt {
- match self.sign {
- Plus | NoSign => self.clone(),
- Minus => BigInt::from_biguint(Plus, self.data.clone()),
- }
- }
- #[inline]
- fn abs_sub(&self, other: &BigInt) -> BigInt {
- if *self <= *other {
- Zero::zero()
- } else {
- self - other
- }
- }
- #[inline]
- fn signum(&self) -> BigInt {
- match self.sign {
- Plus => BigInt::from_biguint(Plus, One::one()),
- Minus => BigInt::from_biguint(Minus, One::one()),
- NoSign => Zero::zero(),
- }
- }
- #[inline]
- fn is_positive(&self) -> bool {
- self.sign == Plus
- }
- #[inline]
- fn is_negative(&self) -> bool {
- self.sign == Minus
- }
- }
- // We want to forward to BigUint::add, but it's not clear how that will go until
- // we compare both sign and magnitude. So we duplicate this body for every
- // val/ref combination, deferring that decision to BigUint's own forwarding.
- macro_rules! bigint_add {
- ($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
- match ($a.sign, $b.sign) {
- (_, NoSign) => $a_owned,
- (NoSign, _) => $b_owned,
- // same sign => keep the sign with the sum of magnitudes
- (Plus, Plus) | (Minus, Minus) =>
- BigInt::from_biguint($a.sign, $a_data + $b_data),
- // opposite signs => keep the sign of the larger with the difference of magnitudes
- (Plus, Minus) | (Minus, Plus) =>
- match $a.data.cmp(&$b.data) {
- Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
- Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
- Equal => Zero::zero(),
- },
- }
- };
- }
- impl<'a, 'b> Add<&'b BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: &BigInt) -> BigInt {
- bigint_add!(self,
- self.clone(),
- &self.data,
- other,
- other.clone(),
- &other.data)
- }
- }
- impl<'a> Add<BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: BigInt) -> BigInt {
- bigint_add!(self, self.clone(), &self.data, other, other, other.data)
- }
- }
- impl<'a> Add<&'a BigInt> for BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: &BigInt) -> BigInt {
- bigint_add!(self, self, self.data, other, other.clone(), &other.data)
- }
- }
- impl Add<BigInt> for BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: BigInt) -> BigInt {
- bigint_add!(self, self, self.data, other, other, other.data)
- }
- }
- // We want to forward to BigUint::sub, but it's not clear how that will go until
- // we compare both sign and magnitude. So we duplicate this body for every
- // val/ref combination, deferring that decision to BigUint's own forwarding.
- macro_rules! bigint_sub {
- ($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
- match ($a.sign, $b.sign) {
- (_, NoSign) => $a_owned,
- (NoSign, _) => -$b_owned,
- // opposite signs => keep the sign of the left with the sum of magnitudes
- (Plus, Minus) | (Minus, Plus) =>
- BigInt::from_biguint($a.sign, $a_data + $b_data),
- // same sign => keep or toggle the sign of the left with the difference of magnitudes
- (Plus, Plus) | (Minus, Minus) =>
- match $a.data.cmp(&$b.data) {
- Less => BigInt::from_biguint(-$a.sign, $b_data - $a_data),
- Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
- Equal => Zero::zero(),
- },
- }
- };
- }
- impl<'a, 'b> Sub<&'b BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: &BigInt) -> BigInt {
- bigint_sub!(self,
- self.clone(),
- &self.data,
- other,
- other.clone(),
- &other.data)
- }
- }
- impl<'a> Sub<BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigInt) -> BigInt {
- bigint_sub!(self, self.clone(), &self.data, other, other, other.data)
- }
- }
- impl<'a> Sub<&'a BigInt> for BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: &BigInt) -> BigInt {
- bigint_sub!(self, self, self.data, other, other.clone(), &other.data)
- }
- }
- impl Sub<BigInt> for BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigInt) -> BigInt {
- bigint_sub!(self, self, self.data, other, other, other.data)
- }
- }
- forward_all_binop_to_ref_ref!(impl Mul for BigInt, mul);
- impl<'a, 'b> Mul<&'b BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn mul(self, other: &BigInt) -> BigInt {
- BigInt::from_biguint(self.sign * other.sign, &self.data * &other.data)
- }
- }
- forward_all_binop_to_ref_ref!(impl Div for BigInt, div);
- impl<'a, 'b> Div<&'b BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn div(self, other: &BigInt) -> BigInt {
- let (q, _) = self.div_rem(other);
- q
- }
- }
- forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
- impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: &BigInt) -> BigInt {
- let (_, r) = self.div_rem(other);
- r
- }
- }
- impl Neg for BigInt {
- type Output = BigInt;
- #[inline]
- fn neg(mut self) -> BigInt {
- self.sign = -self.sign;
- self
- }
- }
- impl<'a> Neg for &'a BigInt {
- type Output = BigInt;
- #[inline]
- fn neg(self) -> BigInt {
- -self.clone()
- }
- }
- impl CheckedAdd for BigInt {
- #[inline]
- fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
- return Some(self.add(v));
- }
- }
- impl CheckedSub for BigInt {
- #[inline]
- fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
- return Some(self.sub(v));
- }
- }
- impl CheckedMul for BigInt {
- #[inline]
- fn checked_mul(&self, v: &BigInt) -> Option<BigInt> {
- return Some(self.mul(v));
- }
- }
- impl CheckedDiv for BigInt {
- #[inline]
- fn checked_div(&self, v: &BigInt) -> Option<BigInt> {
- if v.is_zero() {
- return None;
- }
- return Some(self.div(v));
- }
- }
- impl Integer for BigInt {
- #[inline]
- fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
- // r.sign == self.sign
- let (d_ui, r_ui) = self.data.div_mod_floor(&other.data);
- let d = BigInt::from_biguint(self.sign, d_ui);
- let r = BigInt::from_biguint(self.sign, r_ui);
- if other.is_negative() {
- (-d, r)
- } else {
- (d, r)
- }
- }
- #[inline]
- fn div_floor(&self, other: &BigInt) -> BigInt {
- let (d, _) = self.div_mod_floor(other);
- d
- }
- #[inline]
- fn mod_floor(&self, other: &BigInt) -> BigInt {
- let (_, m) = self.div_mod_floor(other);
- m
- }
- fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
- // m.sign == other.sign
- let (d_ui, m_ui) = self.data.div_rem(&other.data);
- let d = BigInt::from_biguint(Plus, d_ui);
- let m = BigInt::from_biguint(Plus, m_ui);
- let one: BigInt = One::one();
- match (self.sign, other.sign) {
- (_, NoSign) => panic!(),
- (Plus, Plus) | (NoSign, Plus) => (d, m),
- (Plus, Minus) | (NoSign, Minus) => {
- if m.is_zero() {
- (-d, Zero::zero())
- } else {
- (-d - one, m + other)
- }
- }
- (Minus, Plus) => {
- if m.is_zero() {
- (-d, Zero::zero())
- } else {
- (-d - one, other - m)
- }
- }
- (Minus, Minus) => (d, -m),
- }
- }
- /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
- ///
- /// The result is always positive.
- #[inline]
- fn gcd(&self, other: &BigInt) -> BigInt {
- BigInt::from_biguint(Plus, self.data.gcd(&other.data))
- }
- /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
- #[inline]
- fn lcm(&self, other: &BigInt) -> BigInt {
- BigInt::from_biguint(Plus, self.data.lcm(&other.data))
- }
- /// Deprecated, use `is_multiple_of` instead.
- #[inline]
- fn divides(&self, other: &BigInt) -> bool {
- return self.is_multiple_of(other);
- }
- /// Returns `true` if the number is a multiple of `other`.
- #[inline]
- fn is_multiple_of(&self, other: &BigInt) -> bool {
- self.data.is_multiple_of(&other.data)
- }
- /// Returns `true` if the number is divisible by `2`.
- #[inline]
- fn is_even(&self) -> bool {
- self.data.is_even()
- }
- /// Returns `true` if the number is not divisible by `2`.
- #[inline]
- fn is_odd(&self) -> bool {
- self.data.is_odd()
- }
- }
- impl ToPrimitive for BigInt {
- #[inline]
- fn to_i64(&self) -> Option<i64> {
- match self.sign {
- Plus => self.data.to_i64(),
- NoSign => Some(0),
- Minus => {
- self.data.to_u64().and_then(|n| {
- let m: u64 = 1 << 63;
- if n < m {
- Some(-(n as i64))
- } else if n == m {
- Some(i64::MIN)
- } else {
- None
- }
- })
- }
- }
- }
- #[inline]
- fn to_u64(&self) -> Option<u64> {
- match self.sign {
- Plus => self.data.to_u64(),
- NoSign => Some(0),
- Minus => None,
- }
- }
- #[inline]
- fn to_f32(&self) -> Option<f32> {
- self.data.to_f32().map(|n| {
- if self.sign == Minus {
- -n
- } else {
- n
- }
- })
- }
- #[inline]
- fn to_f64(&self) -> Option<f64> {
- self.data.to_f64().map(|n| {
- if self.sign == Minus {
- -n
- } else {
- n
- }
- })
- }
- }
- 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))
- }
- #[inline]
- fn from_f64(n: f64) -> Option<BigInt> {
- if n >= 0.0 {
- BigUint::from_f64(n).map(|x| BigInt::from_biguint(Plus, x))
- } else {
- BigUint::from_f64(-n).map(|x| BigInt::from_biguint(Minus, x))
- }
- }
- }
- impl From<i64> for BigInt {
- #[inline]
- fn from(n: i64) -> Self {
- if n >= 0 {
- BigInt::from(n as u64)
- } else {
- 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<u64> 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<BigUint> for BigInt {
- #[inline]
- fn from(n: BigUint) -> Self {
- if n.is_zero() {
- BigInt::zero()
- } else {
- BigInt {
- sign: Plus,
- data: n,
- }
- }
- }
- }
- #[cfg(feature = "serde")]
- impl serde::Serialize for BigInt {
- fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
- where S: serde::Serializer
- {
- (self.sign, &self.data).serialize(serializer)
- }
- }
- #[cfg(feature = "serde")]
- impl serde::Deserialize for BigInt {
- fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
- where D: serde::Deserializer
- {
- let (sign, data) = try!(serde::Deserialize::deserialize(deserializer));
- Ok(BigInt {
- sign: sign,
- data: data,
- })
- }
- }
- /// A generic trait for converting a value to a `BigInt`.
- pub trait ToBigInt {
- /// Converts the value of `self` to a `BigInt`.
- fn to_bigint(&self) -> Option<BigInt>;
- }
- impl ToBigInt for BigInt {
- #[inline]
- fn to_bigint(&self) -> Option<BigInt> {
- Some(self.clone())
- }
- }
- impl ToBigInt for BigUint {
- #[inline]
- fn to_bigint(&self) -> Option<BigInt> {
- if self.is_zero() {
- Some(Zero::zero())
- } else {
- Some(BigInt {
- sign: Plus,
- data: self.clone(),
- })
- }
- }
- }
- impl biguint::ToBigUint for BigInt {
- #[inline]
- fn to_biguint(&self) -> Option<BigUint> {
- match self.sign() {
- Plus => Some(self.data.clone()),
- NoSign => Some(Zero::zero()),
- Minus => None,
- }
- }
- }
- macro_rules! impl_to_bigint {
- ($T:ty, $from_ty:path) => {
- impl ToBigInt for $T {
- #[inline]
- fn to_bigint(&self) -> Option<BigInt> {
- $from_ty(*self)
- }
- }
- }
- }
- impl_to_bigint!(isize, FromPrimitive::from_isize);
- impl_to_bigint!(i8, FromPrimitive::from_i8);
- impl_to_bigint!(i16, FromPrimitive::from_i16);
- impl_to_bigint!(i32, FromPrimitive::from_i32);
- impl_to_bigint!(i64, FromPrimitive::from_i64);
- impl_to_bigint!(usize, FromPrimitive::from_usize);
- impl_to_bigint!(u8, FromPrimitive::from_u8);
- impl_to_bigint!(u16, FromPrimitive::from_u16);
- impl_to_bigint!(u32, FromPrimitive::from_u32);
- impl_to_bigint!(u64, FromPrimitive::from_u64);
- impl_to_bigint!(f32, FromPrimitive::from_f32);
- impl_to_bigint!(f64, FromPrimitive::from_f64);
- pub trait RandBigInt {
- /// Generate a random `BigUint` of the given bit size.
- fn gen_biguint(&mut self, bit_size: usize) -> BigUint;
- /// Generate a random BigInt of the given bit size.
- fn gen_bigint(&mut self, bit_size: usize) -> BigInt;
- /// Generate a random `BigUint` less than the given bound. Fails
- /// when the bound is zero.
- fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint;
- /// Generate a random `BigUint` within the given range. The lower
- /// bound is inclusive; the upper bound is exclusive. Fails when
- /// the upper bound is not greater than the lower bound.
- fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint;
- /// Generate a random `BigInt` within the given range. The lower
- /// bound is inclusive; the upper bound is exclusive. Fails when
- /// the upper bound is not greater than the lower bound.
- fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt;
- }
- #[cfg(any(feature = "rand", test))]
- impl<R: Rng> RandBigInt for R {
- fn gen_biguint(&mut self, bit_size: usize) -> BigUint {
- let (digits, rem) = bit_size.div_rem(&big_digit::BITS);
- let mut data = Vec::with_capacity(digits + 1);
- for _ in 0..digits {
- data.push(self.gen());
- }
- if rem > 0 {
- let final_digit: BigDigit = self.gen();
- data.push(final_digit >> (big_digit::BITS - rem));
- }
- BigUint::new(data)
- }
- fn gen_bigint(&mut self, bit_size: usize) -> BigInt {
- // Generate a random BigUint...
- let biguint = self.gen_biguint(bit_size);
- // ...and then randomly assign it a Sign...
- let sign = if biguint.is_zero() {
- // ...except that if the BigUint is zero, we need to try
- // again with probability 0.5. This is because otherwise,
- // the probability of generating a zero BigInt would be
- // double that of any other number.
- if self.gen() {
- return self.gen_bigint(bit_size);
- } else {
- NoSign
- }
- } else if self.gen() {
- Plus
- } else {
- Minus
- };
- BigInt::from_biguint(sign, biguint)
- }
- fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
- assert!(!bound.is_zero());
- let bits = bound.bits();
- loop {
- let n = self.gen_biguint(bits);
- if n < *bound {
- return n;
- }
- }
- }
- fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint {
- assert!(*lbound < *ubound);
- return lbound + self.gen_biguint_below(&(ubound - lbound));
- }
- fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt {
- assert!(*lbound < *ubound);
- let delta = (ubound - lbound).to_biguint().unwrap();
- return lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
- }
- }
- impl BigInt {
- /// Creates and initializes a BigInt.
- ///
- /// The digits are in little-endian base 2^32.
- #[inline]
- pub fn new(sign: Sign, digits: Vec<BigDigit>) -> BigInt {
- BigInt::from_biguint(sign, BigUint::new(digits))
- }
- /// Creates and initializes a `BigInt`.
- ///
- /// The digits are in little-endian base 2^32.
- #[inline]
- pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
- if sign == NoSign || data.is_zero() {
- return BigInt {
- sign: NoSign,
- data: Zero::zero(),
- };
- }
- BigInt {
- sign: sign,
- data: data,
- }
- }
- /// Creates and initializes a `BigInt`.
- #[inline]
- pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
- BigInt::from_biguint(sign, BigUint::from_slice(slice))
- }
- /// Creates and initializes a `BigInt`.
- ///
- /// The bytes are in big-endian byte order.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{BigInt, Sign};
- ///
- /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"A"),
- /// BigInt::parse_bytes(b"65", 10).unwrap());
- /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"AA"),
- /// BigInt::parse_bytes(b"16705", 10).unwrap());
- /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"AB"),
- /// BigInt::parse_bytes(b"16706", 10).unwrap());
- /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"Hello world!"),
- /// BigInt::parse_bytes(b"22405534230753963835153736737", 10).unwrap());
- /// ```
- #[inline]
- pub fn from_bytes_be(sign: Sign, bytes: &[u8]) -> BigInt {
- BigInt::from_biguint(sign, BigUint::from_bytes_be(bytes))
- }
- /// Creates and initializes a `BigInt`.
- ///
- /// The bytes are in little-endian byte order.
- #[inline]
- pub fn from_bytes_le(sign: Sign, bytes: &[u8]) -> BigInt {
- BigInt::from_biguint(sign, BigUint::from_bytes_le(bytes))
- }
- /// Creates and initializes a `BigInt` from an array of bytes in
- /// two's complement binary representation.
- ///
- /// The digits are in big-endian base 2^8.
- #[inline]
- pub fn from_signed_bytes_be(digits: &[u8]) -> BigInt {
- let sign = match digits.first() {
- Some(v) if *v > 0x7f => Sign::Minus,
- Some(_) => Sign::Plus,
- None => return BigInt::zero(),
- };
- if sign == Sign::Minus {
- // two's-complement the content to retrieve the magnitude
- let mut digits = Vec::from(digits);
- twos_complement_be(&mut digits);
- BigInt::from_biguint(sign, BigUint::from_bytes_be(&*digits))
- } else {
- BigInt::from_biguint(sign, BigUint::from_bytes_be(digits))
- }
- }
- /// Creates and initializes a `BigInt` from an array of bytes in two's complement.
- ///
- /// The digits are in little-endian base 2^8.
- #[inline]
- pub fn from_signed_bytes_le(digits: &[u8]) -> BigInt {
- let sign = match digits.last() {
- Some(v) if *v > 0x7f => Sign::Minus,
- Some(_) => Sign::Plus,
- None => return BigInt::zero(),
- };
- if sign == Sign::Minus {
- // two's-complement the content to retrieve the magnitude
- let mut digits = Vec::from(digits);
- twos_complement_le(&mut digits);
- BigInt::from_biguint(sign, BigUint::from_bytes_le(&*digits))
- } else {
- BigInt::from_biguint(sign, BigUint::from_bytes_le(digits))
- }
- }
- /// Creates and initializes a `BigInt`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{BigInt, ToBigInt};
- ///
- /// assert_eq!(BigInt::parse_bytes(b"1234", 10), ToBigInt::to_bigint(&1234));
- /// assert_eq!(BigInt::parse_bytes(b"ABCD", 16), ToBigInt::to_bigint(&0xABCD));
- /// assert_eq!(BigInt::parse_bytes(b"G", 16), None);
- /// ```
- #[inline]
- pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigInt> {
- str::from_utf8(buf).ok().and_then(|s| BigInt::from_str_radix(s, radix).ok())
- }
- /// Creates and initializes a `BigInt`. Each u8 of the input slice is
- /// interpreted as one digit of the number
- /// and must therefore be less than `radix`.
- ///
- /// The bytes are in big-endian byte order.
- /// `radix` must be in the range `2...256`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{BigInt, Sign};
- ///
- /// let inbase190 = vec![15, 33, 125, 12, 14];
- /// let a = BigInt::from_radix_be(Sign::Minus, &inbase190, 190).unwrap();
- /// assert_eq!(a.to_radix_be(190), (Sign:: Minus, inbase190));
- /// ```
- pub fn from_radix_be(sign: Sign, buf: &[u8], radix: u32) -> Option<BigInt> {
- BigUint::from_radix_be(buf, radix).map(|u| BigInt::from_biguint(sign, u))
- }
- /// Creates and initializes a `BigInt`. Each u8 of the input slice is
- /// interpreted as one digit of the number
- /// and must therefore be less than `radix`.
- ///
- /// The bytes are in little-endian byte order.
- /// `radix` must be in the range `2...256`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{BigInt, Sign};
- ///
- /// let inbase190 = vec![14, 12, 125, 33, 15];
- /// let a = BigInt::from_radix_be(Sign::Minus, &inbase190, 190).unwrap();
- /// assert_eq!(a.to_radix_be(190), (Sign::Minus, inbase190));
- /// ```
- pub fn from_radix_le(sign: Sign, buf: &[u8], radix: u32) -> Option<BigInt> {
- BigUint::from_radix_le(buf, radix).map(|u| BigInt::from_biguint(sign, u))
- }
- /// Returns the sign and the byte representation of the `BigInt` in big-endian byte order.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{ToBigInt, Sign};
- ///
- /// let i = -1125.to_bigint().unwrap();
- /// assert_eq!(i.to_bytes_be(), (Sign::Minus, vec![4, 101]));
- /// ```
- #[inline]
- pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) {
- (self.sign, self.data.to_bytes_be())
- }
- /// Returns the sign and the byte representation of the `BigInt` in little-endian byte order.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{ToBigInt, Sign};
- ///
- /// let i = -1125.to_bigint().unwrap();
- /// assert_eq!(i.to_bytes_le(), (Sign::Minus, vec![101, 4]));
- /// ```
- #[inline]
- pub fn to_bytes_le(&self) -> (Sign, Vec<u8>) {
- (self.sign, self.data.to_bytes_le())
- }
- /// Returns the two's complement byte representation of the `BigInt` in big-endian byte order.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::ToBigInt;
- ///
- /// let i = -1125.to_bigint().unwrap();
- /// assert_eq!(i.to_signed_bytes_be(), vec![251, 155]);
- /// ```
- #[inline]
- pub fn to_signed_bytes_be(&self) -> Vec<u8> {
- let mut bytes = self.data.to_bytes_be();
- let first_byte = bytes.first().map(|v| *v).unwrap_or(0);
- if first_byte > 0x7f && !(first_byte == 0x80 && bytes.iter().skip(1).all(Zero::is_zero)) {
- // msb used by magnitude, extend by 1 byte
- bytes.insert(0, 0);
- }
- if self.sign == Sign::Minus {
- twos_complement_be(&mut bytes);
- }
- bytes
- }
- /// Returns the two's complement byte representation of the `BigInt` in little-endian byte order.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::ToBigInt;
- ///
- /// let i = -1125.to_bigint().unwrap();
- /// assert_eq!(i.to_signed_bytes_le(), vec![155, 251]);
- /// ```
- #[inline]
- pub fn to_signed_bytes_le(&self) -> Vec<u8> {
- let mut bytes = self.data.to_bytes_le();
- let last_byte = bytes.last().map(|v| *v).unwrap_or(0);
- if last_byte > 0x7f && !(last_byte == 0x80 && bytes.iter().rev().skip(1).all(Zero::is_zero)) {
- // msb used by magnitude, extend by 1 byte
- bytes.push(0);
- }
- if self.sign == Sign::Minus {
- twos_complement_le(&mut bytes);
- }
- bytes
- }
- /// Returns the integer formatted as a string in the given radix.
- /// `radix` must be in the range `2...36`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::BigInt;
- ///
- /// let i = BigInt::parse_bytes(b"ff", 16).unwrap();
- /// assert_eq!(i.to_str_radix(16), "ff");
- /// ```
- #[inline]
- pub fn to_str_radix(&self, radix: u32) -> String {
- let mut v = to_str_radix_reversed(&self.data, radix);
- if self.is_negative() {
- v.push(b'-');
- }
- v.reverse();
- unsafe { String::from_utf8_unchecked(v) }
- }
- /// Returns the integer in the requested base in big-endian digit order.
- /// The output is not given in a human readable alphabet but as a zero
- /// based u8 number.
- /// `radix` must be in the range `2...256`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{BigInt, Sign};
- ///
- /// assert_eq!(BigInt::from(-0xFFFFi64).to_radix_be(159),
- /// (Sign::Minus, vec![2, 94, 27]));
- /// // 0xFFFF = 65535 = 2*(159^2) + 94*159 + 27
- /// ```
- #[inline]
- pub fn to_radix_be(&self, radix: u32) -> (Sign, Vec<u8>) {
- (self.sign, self.data.to_radix_be(radix))
- }
- /// Returns the integer in the requested base in little-endian digit order.
- /// The output is not given in a human readable alphabet but as a zero
- /// based u8 number.
- /// `radix` must be in the range `2...256`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{BigInt, Sign};
- ///
- /// assert_eq!(BigInt::from(-0xFFFFi64).to_radix_le(159),
- /// (Sign::Minus, vec![27, 94, 2]));
- /// // 0xFFFF = 65535 = 27 + 94*159 + 2*(159^2)
- /// ```
- #[inline]
- pub fn to_radix_le(&self, radix: u32) -> (Sign, Vec<u8>) {
- (self.sign, self.data.to_radix_le(radix))
- }
- /// Returns the sign of the `BigInt` as a `Sign`.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_bigint::{ToBigInt, Sign};
- ///
- /// assert_eq!(ToBigInt::to_bigint(&1234).unwrap().sign(), Sign::Plus);
- /// assert_eq!(ToBigInt::to_bigint(&-4321).unwrap().sign(), Sign::Minus);
- /// assert_eq!(ToBigInt::to_bigint(&0).unwrap().sign(), Sign::NoSign);
- /// ```
- #[inline]
- pub fn sign(&self) -> Sign {
- self.sign
- }
- /// Determines the fewest bits necessary to express the `BigInt`,
- /// not including the sign.
- #[inline]
- pub fn bits(&self) -> usize {
- self.data.bits()
- }
- /// Converts this `BigInt` into a `BigUint`, if it's not negative.
- #[inline]
- pub fn to_biguint(&self) -> Option<BigUint> {
- match self.sign {
- Plus => Some(self.data.clone()),
- NoSign => Some(Zero::zero()),
- Minus => None,
- }
- }
- #[inline]
- pub fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
- return Some(self.add(v));
- }
- #[inline]
- pub fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
- return Some(self.sub(v));
- }
- #[inline]
- pub fn checked_mul(&self, v: &BigInt) -> Option<BigInt> {
- return Some(self.mul(v));
- }
- #[inline]
- pub fn checked_div(&self, v: &BigInt) -> Option<BigInt> {
- if v.is_zero() {
- return None;
- }
- return Some(self.div(v));
- }
- }
- /// Perform in-place two's complement of the given binary representation,
- /// in little-endian byte order.
- #[inline]
- fn twos_complement_le(digits: &mut [u8]) {
- twos_complement(digits)
- }
- /// Perform in-place two's complement of the given binary representation
- /// in big-endian byte order.
- #[inline]
- fn twos_complement_be(digits: &mut [u8]) {
- twos_complement(digits.iter_mut().rev())
- }
- /// Perform in-place two's complement of the given digit iterator
- /// starting from the least significant byte.
- #[inline]
- fn twos_complement<'a, I>(digits: I)
- where I: IntoIterator<Item = &'a mut u8>
- {
- let mut carry = true;
- for mut d in digits {
- *d = d.not();
- if carry {
- *d = d.wrapping_add(1);
- carry = d.is_zero();
- }
- }
- }
|