Merge pull request #1608 from ethcore/pow-opt
is_zero() and pow() optimisations for uint
This commit is contained in:
commit
0f83ef6a0b
@ -687,24 +687,25 @@ macro_rules! construct_uint {
|
|||||||
/// Fast exponentation by squaring
|
/// Fast exponentation by squaring
|
||||||
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||||
fn pow(self, expon: Self) -> Self {
|
fn pow(self, expon: Self) -> Self {
|
||||||
if expon == Self::zero() {
|
if expon.is_zero() {
|
||||||
return Self::one()
|
return Self::one()
|
||||||
}
|
}
|
||||||
let is_even = |x : &Self| x.low_u64() & 1 == 0;
|
let is_even = |x : &Self| x.low_u64() & 1 == 0;
|
||||||
|
|
||||||
let u_one = Self::one();
|
let u_one = Self::one();
|
||||||
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;
|
||||||
while n > u_one {
|
while n > u_one {
|
||||||
if is_even(&n) {
|
if is_even(&n) {
|
||||||
x = x * x;
|
x = x * x;
|
||||||
n = n / u_two;
|
n = n >> 1;
|
||||||
} else {
|
} else {
|
||||||
y = x * y;
|
y = x * y;
|
||||||
x = x * x;
|
x = x * x;
|
||||||
n = (n - u_one) / u_two;
|
// to reduce odd number by 1 we should just clear the last bit
|
||||||
|
n.0[$n_words-1] = n.0[$n_words-1] & ((!0u64)>>1);
|
||||||
|
n = n >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x * y
|
x * y
|
||||||
@ -713,13 +714,11 @@ macro_rules! construct_uint {
|
|||||||
/// Fast exponentation by squaring
|
/// Fast exponentation by squaring
|
||||||
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||||
fn overflowing_pow(self, expon: Self) -> (Self, bool) {
|
fn overflowing_pow(self, expon: Self) -> (Self, bool) {
|
||||||
if expon == Self::zero() {
|
if expon.is_zero() { return (Self::one(), false) }
|
||||||
return (Self::one(), false)
|
|
||||||
}
|
|
||||||
let is_even = |x : &Self| x.low_u64() & 1 == 0;
|
let is_even = |x : &Self| x.low_u64() & 1 == 0;
|
||||||
|
|
||||||
let u_one = Self::one();
|
let u_one = Self::one();
|
||||||
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;
|
||||||
@ -728,11 +727,11 @@ macro_rules! construct_uint {
|
|||||||
while n > u_one {
|
while n > u_one {
|
||||||
if is_even(&n) {
|
if is_even(&n) {
|
||||||
x = overflowing!(x.overflowing_mul(x), overflow);
|
x = overflowing!(x.overflowing_mul(x), overflow);
|
||||||
n = n / u_two;
|
n = n >> 1;
|
||||||
} else {
|
} else {
|
||||||
y = overflowing!(x.overflowing_mul(y), overflow);
|
y = overflowing!(x.overflowing_mul(y), overflow);
|
||||||
x = overflowing!(x.overflowing_mul(x), overflow);
|
x = overflowing!(x.overflowing_mul(x), overflow);
|
||||||
n = (n - u_one) / u_two;
|
n = (n - u_one) >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let res = overflowing!(x.overflowing_mul(y), overflow);
|
let res = overflowing!(x.overflowing_mul(y), overflow);
|
||||||
@ -1068,7 +1067,7 @@ macro_rules! construct_uint {
|
|||||||
|
|
||||||
impl fmt::Display for $name {
|
impl fmt::Display for $name {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if *self == $name::zero() {
|
if self.is_zero() {
|
||||||
return write!(f, "0");
|
return write!(f, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1076,7 +1075,7 @@ macro_rules! construct_uint {
|
|||||||
let mut current = *self;
|
let mut current = *self;
|
||||||
let ten = $name::from(10);
|
let ten = $name::from(10);
|
||||||
|
|
||||||
while current != $name::zero() {
|
while !current.is_zero() {
|
||||||
s = format!("{}{}", (current % ten).low_u32(), s);
|
s = format!("{}{}", (current % ten).low_u32(), s);
|
||||||
current = current / ten;
|
current = current / ten;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user