pub trait BigInt<const BASE: usize>where
Self: GetBack<Item = Digit> + Clone + Default + Debug + Display + PartialEq + Eq + PartialOrd + Ord + Neg<Output = Self> + Add<Output = Self> + AddAssign + Sub<Output = Self> + SubAssign + Div<Output = Self> + DivAssign + Mul<Output = Self> + MulAssign + Shl<Output = Self> + ShlAssign + Shr<Output = Self> + ShrAssign + FromStr<Err = BigIntError> + FromIterator<Digit> + From<Vec<Digit>> + From<u8> + From<u16> + From<u32> + From<u64> + From<u128> + From<usize> + From<i8> + From<i16> + From<i32> + From<i64> + From<i128> + From<isize> + Into<u8> + Into<u16> + Into<u32> + Into<u64> + Into<u128> + Into<usize> + Into<i8> + Into<i16> + Into<i32> + Into<i64> + Into<i128> + Into<isize>,{
type Builder: BigIntBuilder<{ BASE }> + Build<Self>;
type DigitIterator<'a>: DoubleEndedIterator<Item = Digit>
where Self: 'a;
Show 41 methods
// Required methods
fn len(&self) -> usize;
fn get_digit(&self, digit: usize) -> Option<Digit>;
fn set_digit(&mut self, digit: usize, value: Digit);
fn zero() -> Self;
fn sign(&self) -> Sign;
fn with_sign(self, sign: Sign) -> Self;
fn set_sign(&mut self, sign: Sign);
fn push_back(&mut self, digit: Digit);
fn push_front(&mut self, digit: Digit);
fn iter<'a>(&'a self) -> Self::DigitIterator<'a>;
// Provided methods
fn get_back_inner(&self, index: usize) -> Option<Digit> { ... }
fn default_inner() -> Self { ... }
fn fmt_inner(&self, f: &mut Formatter<'_>) -> Result { ... }
fn partial_cmp_inner(&self, other: &Self) -> Option<Ordering> { ... }
fn cmp_inner(&self, other: &Self) -> Ordering { ... }
fn neg_inner(self) -> Self { ... }
fn add_inner(self, rhs: Self) -> Self { ... }
fn add_assign_inner(&mut self, rhs: Self) { ... }
fn sub_inner(self, rhs: Self) -> Self { ... }
fn sub_assign_inner(&mut self, rhs: Self) { ... }
fn mul_inner(self, rhs: Self) -> Self { ... }
fn mul_assign_inner(&mut self, rhs: Self) { ... }
fn div_inner(self, rhs: Self) -> Self { ... }
fn div_assign_inner(&mut self, rhs: Self) { ... }
fn from_str_inner(s: &str) -> Result<Self, BigIntError> { ... }
fn from_iter_inner<T: IntoIterator<Item = Digit>>(iter: T) -> Self { ... }
fn from_u128_inner(value: u128) -> Self { ... }
fn from_i128_inner(value: i128) -> Self { ... }
fn into_u128_inner(self) -> u128 { ... }
fn into_i128_inner(self) -> i128 { ... }
fn shr_inner(self, amount: usize) -> Self { ... }
fn shr_assign_inner(&mut self, amount: usize) { ... }
fn shl_inner(self, amount: usize) -> Self { ... }
fn shl_assign_inner(&mut self, amount: usize) { ... }
fn normalized(self) -> Self { ... }
fn normalize(&mut self) { ... }
fn display(&self, alphabet: &str) -> Result<String, BigIntError> { ... }
fn parse(value: &str, alphabet: &str) -> Result<Self, ParseError> { ... }
fn div_rem(self, other: Self) -> Result<(Self, Self), BigIntError> { ... }
fn convert<const TO: usize, T: BigInt<{ TO }>>(self) -> T { ... }
fn cmp_magnitude(&self, rhs: &Self) -> Ordering { ... }
}
Expand description
A big int.
Represents an arbitrary precision, arbitrary base natural number.
Supports basic arithmetic operations, as well as all utilities necessary for
coercing to and from various builtin types, such as primitive int types, Vec
s, and String
s.
For implementors:
If implementing this trait for your own type, don’t be alarmed by the massive list of Self
constraints. Use the included derive macro big_int::BigIntTraits
to automatically derive
all traits using default *_inner
implementations pre-provided by BigInt
.
At least one of normalize
or normalized
must be defined to prevent recursion.
At least one of shl_inner
or shl_assign_inner
must be defined to prevent recursion.
At least one of shr_inner
or shr_assign_inner
must be defined to prevent recursion.
use big_int::prelude::*;
let mut a = TightBuilder::<10>::new();
a.push_back(1);
a.push_back(0);
a.push_back(4);
let a: Tight<10> = a.build();
assert_eq!(a, 104.into());
Required Associated Types§
type Builder: BigIntBuilder<{ BASE }> + Build<Self>
type DigitIterator<'a>: DoubleEndedIterator<Item = Digit> where Self: 'a
Required Methods§
sourcefn len(&self) -> usize
fn len(&self) -> usize
The length of the big int in digits.
use big_int::prelude::*;
let a: Tight<10> = 211864.into();
assert_eq!(a.len(), 6);
sourcefn get_digit(&self, digit: usize) -> Option<Digit>
fn get_digit(&self, digit: usize) -> Option<Digit>
Get the digit of the big int at position digit
,
or None if the number does not have that many digits.
use big_int::prelude::*;
let a: Tight<10> = 12345.into();
assert_eq!(a.get_digit(2), Some(3));
assert_eq!(a.get_digit(6), None);
sourcefn set_digit(&mut self, digit: usize, value: Digit)
fn set_digit(&mut self, digit: usize, value: Digit)
Set the digit of the big int to value
at position digit
.
If the set digit causes the leftmost digit of the number to be zero, the number will become denormal, and should be normalized before being used.
use big_int::prelude::*;
let mut a: Tight<10> = 10000.into();
a.set_digit(1, 7);
a.set_digit(4, 9);
assert_eq!(a, 17009.into());
sourcefn zero() -> Self
fn zero() -> Self
The value zero represented as a big int.
use big_int::prelude::*;
let a: Tight<10> = 13.into();
let b = 13.into();
assert_eq!(a - b, BigInt::zero());
sourcefn sign(&self) -> Sign
fn sign(&self) -> Sign
The sign of the big int.
The value zero represented as a big int.
use big_int::prelude::*;
let mut a: Tight<10> = 5.into();
assert_eq!(a.sign(), Positive);
a -= 14.into();
assert_eq!(a.sign(), Negative);
sourcefn with_sign(self, sign: Sign) -> Self
fn with_sign(self, sign: Sign) -> Self
The big in with the given sign.
use big_int::prelude::*;
let a: Tight<10> = 95.into();
assert_eq!(a.with_sign(Negative), (-95).into());
sourcefn set_sign(&mut self, sign: Sign)
fn set_sign(&mut self, sign: Sign)
Set the sign of the big int to sign
.
use big_int::prelude::*;
let mut a: Tight<10> = (-109).into();
a.set_sign(Positive);
assert_eq!(a, 109.into());
sourcefn push_back(&mut self, digit: Digit)
fn push_back(&mut self, digit: Digit)
Append a digit to the right side of the int. Equivalent to (int << 1) + digit
use big_int::prelude::*;
let mut a: Tight<10> = 6.into();
a.push_back(1);
assert_eq!(a, 61.into());
sourcefn push_front(&mut self, digit: Digit)
fn push_front(&mut self, digit: Digit)
Append a digit to the left side of the int. May cause the resulting int to be denormalized; make sure to call .normalize() afterwards to prevent undefined functionality.
use big_int::prelude::*;
let mut a: Tight<10> = 6.into();
a.push_front(1);
assert_eq!(a.normalized(), 16.into());
sourcefn iter<'a>(&'a self) -> Self::DigitIterator<'a>
fn iter<'a>(&'a self) -> Self::DigitIterator<'a>
Iterate over the digits of the int.
implements DoubleEndedIterator
, so digits can be iterated over forward or in reverse.
use big_int::prelude::*;
let a: Tight<10> = 12345.into();
assert_eq!(a.iter().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5]);
assert_eq!(a.iter().rev().collect::<Vec<_>>(), vec![5, 4, 3, 2, 1]);
Provided Methods§
sourcefn get_back_inner(&self, index: usize) -> Option<Digit>
fn get_back_inner(&self, index: usize) -> Option<Digit>
Default implementation of big_int::GetBack
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn default_inner() -> Self
fn default_inner() -> Self
Default implementation of Default
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn fmt_inner(&self, f: &mut Formatter<'_>) -> Result
fn fmt_inner(&self, f: &mut Formatter<'_>) -> Result
Default implementation of Display
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn partial_cmp_inner(&self, other: &Self) -> Option<Ordering>
fn partial_cmp_inner(&self, other: &Self) -> Option<Ordering>
Default implementation of PartialOrd
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn cmp_inner(&self, other: &Self) -> Ordering
fn cmp_inner(&self, other: &Self) -> Ordering
Default implementation of Ord
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn neg_inner(self) -> Self
fn neg_inner(self) -> Self
Default implementation of Neg
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn add_inner(self, rhs: Self) -> Self
fn add_inner(self, rhs: Self) -> Self
Default implementation of Add
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn add_assign_inner(&mut self, rhs: Self)
fn add_assign_inner(&mut self, rhs: Self)
Default implementation of AddAssign
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn sub_inner(self, rhs: Self) -> Self
fn sub_inner(self, rhs: Self) -> Self
Default implementation of Sub
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn sub_assign_inner(&mut self, rhs: Self)
fn sub_assign_inner(&mut self, rhs: Self)
Default implementation of SubAssign
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn mul_inner(self, rhs: Self) -> Self
fn mul_inner(self, rhs: Self) -> Self
Default implementation of Mul
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn mul_assign_inner(&mut self, rhs: Self)
fn mul_assign_inner(&mut self, rhs: Self)
Default implementation of MulAssign
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn div_inner(self, rhs: Self) -> Self
fn div_inner(self, rhs: Self) -> Self
Default implementation of Div
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn div_assign_inner(&mut self, rhs: Self)
fn div_assign_inner(&mut self, rhs: Self)
Default implementation of DivAssign
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn from_str_inner(s: &str) -> Result<Self, BigIntError>
fn from_str_inner(s: &str) -> Result<Self, BigIntError>
Default implementation of FromStr
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn from_iter_inner<T: IntoIterator<Item = Digit>>(iter: T) -> Self
fn from_iter_inner<T: IntoIterator<Item = Digit>>(iter: T) -> Self
Default implementation of FromIterator
.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn from_u128_inner(value: u128) -> Self
fn from_u128_inner(value: u128) -> Self
Default implementation of From<_>
for all unsigned primitive int types.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn from_i128_inner(value: i128) -> Self
fn from_i128_inner(value: i128) -> Self
Default implementation of From<_>
for all signed primitive int types.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn into_u128_inner(self) -> u128
fn into_u128_inner(self) -> u128
Default implementation of Into<_>
for all unsigned primitive int types.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn into_i128_inner(self) -> i128
fn into_i128_inner(self) -> i128
Default implementation of Into<_>
for all signed primitive int types.
Trait implementation may be provided automatically by big_int_proc::BigIntTraits
.
sourcefn shr_inner(self, amount: usize) -> Self
fn shr_inner(self, amount: usize) -> Self
Divide the int by BASE^amount.
Note: works in powers of BASE, not in powers of 2.
Defined in terms of shr_assign
; at least one of shr
or shr_assign
must be defined by implementers.
Also acts as the default implementation of the Shr
trait,
as provided automatically by big_int_proc::BigIntTraits
.
use big_int::prelude::*;
let a: Tight<10> = 600.into();
assert_eq!(a.shr_inner(2), 6.into());
sourcefn shr_assign_inner(&mut self, amount: usize)
fn shr_assign_inner(&mut self, amount: usize)
Divide the int by BASE^amount in place.
Note: works in powers of BASE, not in powers of 2.
Defined in terms of shr
; at least one of shr
or shr_assign
must be defined by implementers.
Also acts as the default implementation of the ShrAssign
trait,
as provided automatically by big_int_proc::BigIntTraits
.
use big_int::prelude::*;
let mut a: Tight<10> = 600.into();
a.shr_assign_inner(2);
assert_eq!(a, 6.into());
sourcefn shl_inner(self, amount: usize) -> Self
fn shl_inner(self, amount: usize) -> Self
Multiply the int by BASE^amount.
Note: works in powers of BASE, not in powers of 2.
Defined in terms of shl_assign
; at least one of shl
or shl_assign
must be defined by implementers.
Also acts as the default implementation of the Shl
trait,
as provided automatically by big_int_proc::BigIntTraits
.
use big_int::prelude::*;
let a: Tight<10> = 3.into();
assert_eq!(a.shl_inner(2), 300.into());
sourcefn shl_assign_inner(&mut self, amount: usize)
fn shl_assign_inner(&mut self, amount: usize)
Multiply the int by BASE^amount in place.
Note: works in powers of BASE, not in powers of 2.
Defined in terms of shl
; at least one of shl
or shl_assign
must be defined by implementers.
Also acts as the default implementation of the ShlAssign
trait,
as provided automatically by big_int_proc::BigIntTraits
.
use big_int::prelude::*;
let mut a: Tight<10> = 3.into();
a.shl_assign_inner(2);
assert_eq!(a, 300.into());
sourcefn normalized(self) -> Self
fn normalized(self) -> Self
Return a normalized version of the int. A normalized int:
- has no trailing zeros
- has at least one digit
- is not negative zero
Additionally,
Tight
s will be aligned to the beginning of their data segment when normalized.
Defined in terms of normalize
; at least one of normalize
or normalized
must be defined by the implementer.
use big_int::prelude::*;
let n = unsafe { Loose::<10>::from_raw_parts(vec![0, 0, 8, 3]) };
assert_eq!(n.normalized(), 83.into());
sourcefn normalize(&mut self)
fn normalize(&mut self)
Normalize a big int in place.
- has no trailing zeros
- has at least one digit
- is not negative zero
Additionally,
Tight
s will be aligned to the beginning of their data segment when normalized.
Defined in terms of normalized
; at least one of normalize
or normalized
must be defined by the implementer.
use big_int::prelude::*;
let mut n = unsafe { Loose::<10>::from_raw_parts(vec![0, 0, 8, 3]) };
n.normalize();
assert_eq!(n, 83.into());
sourcefn display(&self, alphabet: &str) -> Result<String, BigIntError>
fn display(&self, alphabet: &str) -> Result<String, BigIntError>
Convert a big int to a printable string using the provided alphabet alphabet
.
Display
uses this method with the default alphabet STANDARD_ALPHABET
.
use big_int::prelude::*;
assert_eq!(
Loose::<10>::from(6012).display(STANDARD_ALPHABET).unwrap(),
"6012".to_string()
);
sourcefn parse(value: &str, alphabet: &str) -> Result<Self, ParseError>
fn parse(value: &str, alphabet: &str) -> Result<Self, ParseError>
Parse a big int from a value: &str
, referencing the provided alphabet
to determine what characters represent which digits. FromStr
uses this method
with the default alphabet STANDARD_ALPHABET
.
use big_int::prelude::*;
assert_eq!(Loose::parse("125", STANDARD_ALPHABET), Ok(Loose::<10>::from(125)));
sourcefn div_rem(self, other: Self) -> Result<(Self, Self), BigIntError>
fn div_rem(self, other: Self) -> Result<(Self, Self), BigIntError>
Divide one int by another, returning the quotient & remainder as a pair,
or an error if dividing by zero. This algorithm has a different time complexity
than BigInt::div_rem_lowmem
which makes it faster for most use cases, but also uses more memory.
b
- base
d
- number of digits in quotient
Time complexity: O(d * log(b))
Memory complexity: O(d * log(b))
use big_int::prelude::*;
let a: Loose<10> = 999_999_999.into();
let b = 56_789.into();
assert_eq!(a.div_rem(b), Ok((17_609.into(), 2_498.into())));
sourcefn convert<const TO: usize, T: BigInt<{ TO }>>(self) -> T
fn convert<const TO: usize, T: BigInt<{ TO }>>(self) -> T
Convert an int from its own base to another target base.
use big_int::prelude::*;
let a: Loose<16> = Loose::<10>::from(99825).convert();
assert_eq!(a, Loose::<16>::from(99825));
sourcefn cmp_magnitude(&self, rhs: &Self) -> Ordering
fn cmp_magnitude(&self, rhs: &Self) -> Ordering
Compare the absolute magnitude of two big ints, ignoring their sign.
use big_int::prelude::*;
let a: Tight<10> = (-105).into();
let b = 15.into();
assert!(a.cmp_magnitude(&b).is_gt());