123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767 |
- 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, DoubleBigDigit};
- use biguint;
- use biguint::to_str_radix_reversed;
- use biguint::BigUint;
- use UsizePromotion;
- use IsizePromotion;
- #[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
- }
- }
- // A convenience method for getting the absolute value of an i32 in a u32.
- #[inline]
- fn i32_abs_as_u32(a: i32) -> u32 {
- if a == i32::min_value() {
- a as u32
- } else {
- a.abs() as u32
- }
- }
- // A convenience method for getting the absolute value of an i64 in a u64.
- #[inline]
- fn i64_abs_as_u64(a: i64) -> u64 {
- if a == i64::min_value() {
- a as u64
- } else {
- a.abs() as u64
- }
- }
- // 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)
- }
- }
- promote_all_scalars!(impl Add for BigInt, add);
- forward_all_scalar_binop_to_val_val_commutative!(impl Add<BigDigit> for BigInt, add);
- forward_all_scalar_binop_to_val_val_commutative!(impl Add<DoubleBigDigit> for BigInt, add);
- impl Add<BigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: BigDigit) -> BigInt {
- match self.sign {
- NoSign => From::from(other),
- Plus => BigInt::from_biguint(Plus, self.data + other),
- Minus =>
- match self.data.cmp(&From::from(other)) {
- Equal => Zero::zero(),
- Less => BigInt::from_biguint(Plus, other - self.data),
- Greater => BigInt::from_biguint(Minus, self.data - other),
- }
- }
- }
- }
- impl Add<DoubleBigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: DoubleBigDigit) -> BigInt {
- match self.sign {
- NoSign => From::from(other),
- Plus => BigInt::from_biguint(Plus, self.data + other),
- Minus =>
- match self.data.cmp(&From::from(other)) {
- Equal => Zero::zero(),
- Less => BigInt::from_biguint(Plus, other - self.data),
- Greater => BigInt::from_biguint(Minus, self.data - other),
- }
- }
- }
- }
- forward_all_scalar_binop_to_val_val_commutative!(impl Add<i32> for BigInt, add);
- forward_all_scalar_binop_to_val_val_commutative!(impl Add<i64> for BigInt, add);
- impl Add<i32> for BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: i32) -> BigInt {
- if other >= 0 {
- self + other as u32
- } else {
- self - i32_abs_as_u32(other)
- }
- }
- }
- impl Add<i64> for BigInt {
- type Output = BigInt;
- #[inline]
- fn add(self, other: i64) -> BigInt {
- if other >= 0 {
- self + other as u64
- } else {
- self - i64_abs_as_u64(other)
- }
- }
- }
- // 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)
- }
- }
- promote_all_scalars!(impl Sub for BigInt, sub);
- forward_all_scalar_binop_to_val_val!(impl Sub<BigDigit> for BigInt, sub);
- forward_all_scalar_binop_to_val_val!(impl Sub<DoubleBigDigit> for BigInt, sub);
- impl Sub<BigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigDigit) -> BigInt {
- match self.sign {
- NoSign => BigInt::from_biguint(Minus, From::from(other)),
- Minus => BigInt::from_biguint(Minus, self.data + other),
- Plus =>
- match self.data.cmp(&From::from(other)) {
- Equal => Zero::zero(),
- Greater => BigInt::from_biguint(Plus, self.data - other),
- Less => BigInt::from_biguint(Minus, other - self.data),
- }
- }
- }
- }
- impl Sub<BigInt> for BigDigit {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigInt) -> BigInt {
- -(other - self)
- }
- }
- impl Sub<DoubleBigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: DoubleBigDigit) -> BigInt {
- match self.sign {
- NoSign => BigInt::from_biguint(Minus, From::from(other)),
- Minus => BigInt::from_biguint(Minus, self.data + other),
- Plus =>
- match self.data.cmp(&From::from(other)) {
- Equal => Zero::zero(),
- Greater => BigInt::from_biguint(Plus, self.data - other),
- Less => BigInt::from_biguint(Minus, other - self.data),
- }
- }
- }
- }
- impl Sub<BigInt> for DoubleBigDigit {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigInt) -> BigInt {
- -(other - self)
- }
- }
- forward_all_scalar_binop_to_val_val!(impl Sub<i32> for BigInt, sub);
- forward_all_scalar_binop_to_val_val!(impl Sub<i64> for BigInt, sub);
- impl Sub<i32> for BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: i32) -> BigInt {
- if other >= 0 {
- self - other as u32
- } else {
- self + i32_abs_as_u32(other)
- }
- }
- }
- impl Sub<BigInt> for i32 {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigInt) -> BigInt {
- if self >= 0 {
- self as u32 - other
- } else {
- -other - i32_abs_as_u32(self)
- }
- }
- }
- impl Sub<i64> for BigInt {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: i64) -> BigInt {
- if other >= 0 {
- self - other as u64
- } else {
- self + i64_abs_as_u64(other)
- }
- }
- }
- impl Sub<BigInt> for i64 {
- type Output = BigInt;
- #[inline]
- fn sub(self, other: BigInt) -> BigInt {
- if self >= 0 {
- self as u64 - other
- } else {
- -other - i64_abs_as_u64(self)
- }
- }
- }
- 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)
- }
- }
- promote_all_scalars!(impl Mul for BigInt, mul);
- forward_all_scalar_binop_to_val_val_commutative!(impl Mul<BigDigit> for BigInt, mul);
- forward_all_scalar_binop_to_val_val_commutative!(impl Mul<DoubleBigDigit> for BigInt, mul);
- impl Mul<BigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn mul(self, other: BigDigit) -> BigInt {
- BigInt::from_biguint(self.sign, self.data * other)
- }
- }
- impl Mul<DoubleBigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn mul(self, other: DoubleBigDigit) -> BigInt {
- BigInt::from_biguint(self.sign, self.data * other)
- }
- }
- forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i32> for BigInt, mul);
- forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i64> for BigInt, mul);
- impl Mul<i32> for BigInt {
- type Output = BigInt;
- #[inline]
- fn mul(self, other: i32) -> BigInt {
- if other >= 0 {
- self * other as u32
- } else {
- -(self * i32_abs_as_u32(other))
- }
- }
- }
- impl Mul<i64> for BigInt {
- type Output = BigInt;
- #[inline]
- fn mul(self, other: i64) -> BigInt {
- if other >= 0 {
- self * other as u64
- } else {
- -(self * i64_abs_as_u64(other))
- }
- }
- }
- 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
- }
- }
- promote_all_scalars!(impl Div for BigInt, div);
- forward_all_scalar_binop_to_val_val!(impl Div<BigDigit> for BigInt, div);
- forward_all_scalar_binop_to_val_val!(impl Div<DoubleBigDigit> for BigInt, div);
- impl Div<BigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn div(self, other: BigDigit) -> BigInt {
- BigInt::from_biguint(self.sign, self.data / other)
- }
- }
- impl Div<BigInt> for BigDigit {
- type Output = BigInt;
- #[inline]
- fn div(self, other: BigInt) -> BigInt {
- BigInt::from_biguint(other.sign, self / other.data)
- }
- }
- impl Div<DoubleBigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn div(self, other: DoubleBigDigit) -> BigInt {
- BigInt::from_biguint(self.sign, self.data / other)
- }
- }
- impl Div<BigInt> for DoubleBigDigit {
- type Output = BigInt;
- #[inline]
- fn div(self, other: BigInt) -> BigInt {
- BigInt::from_biguint(other.sign, self / other.data)
- }
- }
- forward_all_scalar_binop_to_val_val!(impl Div<i32> for BigInt, div);
- forward_all_scalar_binop_to_val_val!(impl Div<i64> for BigInt, div);
- impl Div<i32> for BigInt {
- type Output = BigInt;
- #[inline]
- fn div(self, other: i32) -> BigInt {
- if other >= 0 {
- self / other as u32
- } else {
- -(self / i32_abs_as_u32(other))
- }
- }
- }
- impl Div<BigInt> for i32 {
- type Output = BigInt;
- #[inline]
- fn div(self, other: BigInt) -> BigInt {
- if self >= 0 {
- self as u32 / other
- } else {
- -(i32_abs_as_u32(self) / other)
- }
- }
- }
- impl Div<i64> for BigInt {
- type Output = BigInt;
- #[inline]
- fn div(self, other: i64) -> BigInt {
- if other >= 0 {
- self / other as u64
- } else {
- -(self / i64_abs_as_u64(other))
- }
- }
- }
- impl Div<BigInt> for i64 {
- type Output = BigInt;
- #[inline]
- fn div(self, other: BigInt) -> BigInt {
- if self >= 0 {
- self as u64 / other
- } else {
- -(i64_abs_as_u64(self) / other)
- }
- }
- }
- 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
- }
- }
- promote_all_scalars!(impl Rem for BigInt, rem);
- forward_all_scalar_binop_to_val_val!(impl Rem<BigDigit> for BigInt, rem);
- forward_all_scalar_binop_to_val_val!(impl Rem<DoubleBigDigit> for BigInt, rem);
- impl Rem<BigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: BigDigit) -> BigInt {
- BigInt::from_biguint(self.sign, self.data % other)
- }
- }
- impl Rem<BigInt> for BigDigit {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: BigInt) -> BigInt {
- BigInt::from_biguint(Plus, self % other.data)
- }
- }
- impl Rem<DoubleBigDigit> for BigInt {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: DoubleBigDigit) -> BigInt {
- BigInt::from_biguint(self.sign, self.data % other)
- }
- }
- impl Rem<BigInt> for DoubleBigDigit {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: BigInt) -> BigInt {
- BigInt::from_biguint(Plus, self % other.data)
- }
- }
- forward_all_scalar_binop_to_val_val!(impl Rem<i32> for BigInt, rem);
- forward_all_scalar_binop_to_val_val!(impl Rem<i64> for BigInt, rem);
- impl Rem<i32> for BigInt {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: i32) -> BigInt {
- if other >= 0 {
- self % other as u32
- } else {
- self % i32_abs_as_u32(other)
- }
- }
- }
- impl Rem<BigInt> for i32 {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: BigInt) -> BigInt {
- if self >= 0 {
- self as u32 % other
- } else {
- -(i32_abs_as_u32(self) % other)
- }
- }
- }
- impl Rem<i64> for BigInt {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: i64) -> BigInt {
- if other >= 0 {
- self % other as u64
- } else {
- self % i64_abs_as_u64(other)
- }
- }
- }
- impl Rem<BigInt> for i64 {
- type Output = BigInt;
- #[inline]
- fn rem(self, other: BigInt) -> BigInt {
- if self >= 0 {
- self as u64 % other
- } else {
- -(i64_abs_as_u64(self) % other)
- }
- }
- }
- 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<sup>32</sup>.
- #[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<sup>32</sup>.
- #[inline]
- pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt {
- if sign == NoSign {
- data.assign_from_slice(&[]);
- } else if data.is_zero() {
- sign = NoSign;
- }
- 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))
- }
- /// Reinitializes a `BigInt`.
- #[inline]
- pub fn assign_from_slice(&mut self, sign: Sign, slice: &[BigDigit]) {
- if sign == NoSign {
- self.data.assign_from_slice(&[]);
- self.sign = NoSign;
- } else {
- self.data.assign_from_slice(slice);
- self.sign = match self.data.is_zero() {
- true => NoSign,
- false => sign,
- }
- }
- }
- /// 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<sup>8</sup>.
- #[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<sup>8</sup>.
- #[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 d in digits {
- *d = d.not();
- if carry {
- *d = d.wrapping_add(1);
- carry = d.is_zero();
- }
- }
- }
|