12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145 |
- use std::default::Default;
- use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub};
- 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))
- }
- /// 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 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 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
- }
- /// 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())
- }
- /// 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));
- }
- }
|