Implementing pow, overflowing_pow only for uint. Adding missing docs.
This commit is contained in:
parent
40947e214b
commit
666cbe7d47
59
src/uint.rs
59
src/uint.rs
@ -58,6 +58,7 @@ macro_rules! panic_on_overflow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Uint: Sized + Default + FromStr + From<u64> + FromJson + fmt::Debug + fmt::Display + PartialOrd + Ord + PartialEq + Eq + Hash {
|
pub trait Uint: Sized + Default + FromStr + From<u64> + FromJson + fmt::Debug + fmt::Display + PartialOrd + Ord + PartialEq + Eq + Hash {
|
||||||
|
|
||||||
/// Size of this type.
|
/// Size of this type.
|
||||||
@ -83,11 +84,19 @@ pub trait Uint: Sized + Default + FromStr + From<u64> + FromJson + fmt::Debug +
|
|||||||
|
|
||||||
/// Return the least number of bits needed to represent the number
|
/// Return the least number of bits needed to represent the number
|
||||||
fn bits(&self) -> usize;
|
fn bits(&self) -> usize;
|
||||||
|
/// Return if specific bit is set
|
||||||
fn bit(&self, index: usize) -> bool;
|
fn bit(&self, index: usize) -> bool;
|
||||||
|
/// Return single byte
|
||||||
fn byte(&self, index: usize) -> u8;
|
fn byte(&self, index: usize) -> u8;
|
||||||
|
/// Get this Uint as slice of bytes
|
||||||
fn to_bytes(&self, bytes: &mut[u8]);
|
fn to_bytes(&self, bytes: &mut[u8]);
|
||||||
|
|
||||||
|
/// Create `Uint(10**n)`
|
||||||
fn exp10(n: usize) -> Self;
|
fn exp10(n: usize) -> Self;
|
||||||
|
/// Return eponentation `self**other`. Panic on overflow.
|
||||||
|
fn pow(self, other: Self) -> Self;
|
||||||
|
/// Return wrapped eponentation `self**other` and flag if there was an overflow
|
||||||
|
fn overflowing_pow(self, other: Self) -> (Self, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! construct_uint {
|
macro_rules! construct_uint {
|
||||||
@ -112,14 +121,12 @@ macro_rules! construct_uint {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Conversion to u32
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn low_u32(&self) -> u32 {
|
fn low_u32(&self) -> u32 {
|
||||||
let &$name(ref arr) = self;
|
let &$name(ref arr) = self;
|
||||||
arr[0] as u32
|
arr[0] as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Conversion to u64
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn low_u64(&self) -> u64 {
|
fn low_u64(&self) -> u64 {
|
||||||
let &$name(ref arr) = self;
|
let &$name(ref arr) = self;
|
||||||
@ -147,6 +154,7 @@ macro_rules! construct_uint {
|
|||||||
}
|
}
|
||||||
arr[0]
|
arr[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the least number of bits needed to represent the number
|
/// Return the least number of bits needed to represent the number
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits(&self) -> usize {
|
fn bits(&self) -> usize {
|
||||||
@ -180,34 +188,33 @@ macro_rules! construct_uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn exp10(n: usize) -> $name {
|
fn exp10(n: usize) -> Self {
|
||||||
match n {
|
match n {
|
||||||
0 => $name::from(1u64),
|
0 => Self::from(1u64),
|
||||||
_ => $name::exp10(n - 1) * $name::from(10u64)
|
_ => Self::exp10(n - 1) * Self::from(10u64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero() -> $name {
|
fn zero() -> Self {
|
||||||
From::from(0u64)
|
From::from(0u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> $name {
|
fn one() -> Self {
|
||||||
From::from(1u64)
|
From::from(1u64)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl $name {
|
/// Fast exponentation by squaring
|
||||||
|
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||||
pub fn pow(self, expon: $name) -> $name {
|
fn pow(self, expon: Self) -> Self {
|
||||||
if expon == $name::zero() {
|
if expon == Self::zero() {
|
||||||
return $name::one()
|
return Self::one()
|
||||||
}
|
}
|
||||||
let is_even = |x : &$name| x.low_u64() & 1 == 0;
|
let is_even = |x : &Self| x.low_u64() & 1 == 0;
|
||||||
|
|
||||||
let u_one = $name::one();
|
let u_one = Self::one();
|
||||||
let u_two = $name::from(2);
|
let u_two = Self::from(2);
|
||||||
let mut y = u_one;
|
let mut y = u_one;
|
||||||
let mut n = expon;
|
let mut n = expon;
|
||||||
let mut x = self;
|
let mut x = self;
|
||||||
@ -224,14 +231,16 @@ macro_rules! construct_uint {
|
|||||||
x * y
|
x * y
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn overflowing_pow(self, expon: $name) -> ($name, bool) {
|
/// Fast exponentation by squaring
|
||||||
if expon == $name::zero() {
|
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||||
return ($name::one(), false)
|
fn overflowing_pow(self, expon: Self) -> (Self, bool) {
|
||||||
|
if expon == Self::zero() {
|
||||||
|
return (Self::one(), false)
|
||||||
}
|
}
|
||||||
let is_even = |x : &$name| x.low_u64() & 1 == 0;
|
let is_even = |x : &Self| x.low_u64() & 1 == 0;
|
||||||
|
|
||||||
let u_one = $name::one();
|
let u_one = Self::one();
|
||||||
let u_two = $name::from(2);
|
let u_two = Self::from(2);
|
||||||
let mut y = u_one;
|
let mut y = u_one;
|
||||||
let mut n = expon;
|
let mut n = expon;
|
||||||
let mut x = self;
|
let mut x = self;
|
||||||
@ -250,9 +259,11 @@ macro_rules! construct_uint {
|
|||||||
let res = overflowing!(x.overflowing_mul(y), overflow);
|
let res = overflowing!(x.overflowing_mul(y), overflow);
|
||||||
(res, overflow)
|
(res, overflow)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $name {
|
||||||
/// Multiplication by u32
|
/// Multiplication by u32
|
||||||
fn mul_u32(self, other: u32) -> $name {
|
fn mul_u32(self, other: u32) -> Self {
|
||||||
let $name(ref arr) = self;
|
let $name(ref arr) = self;
|
||||||
let mut carry = [0u64; $n_words];
|
let mut carry = [0u64; $n_words];
|
||||||
let mut ret = [0u64; $n_words];
|
let mut ret = [0u64; $n_words];
|
||||||
@ -273,7 +284,7 @@ macro_rules! construct_uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Overflowing multiplication by u32
|
/// Overflowing multiplication by u32
|
||||||
fn overflowing_mul_u32(self, other: u32) -> ($name, bool) {
|
fn overflowing_mul_u32(self, other: u32) -> (Self, bool) {
|
||||||
let $name(ref arr) = self;
|
let $name(ref arr) = self;
|
||||||
let mut carry = [0u64; $n_words];
|
let mut carry = [0u64; $n_words];
|
||||||
let mut ret = [0u64; $n_words];
|
let mut ret = [0u64; $n_words];
|
||||||
|
Loading…
Reference in New Issue
Block a user