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
 | 
			
		||||
			/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
 | 
			
		||||
			fn pow(self, expon: Self) -> Self {
 | 
			
		||||
				if expon == Self::zero() {
 | 
			
		||||
				if expon.is_zero() {
 | 
			
		||||
					return Self::one()
 | 
			
		||||
				}
 | 
			
		||||
				let is_even = |x : &Self| x.low_u64() & 1 == 0;
 | 
			
		||||
 | 
			
		||||
				let u_one = Self::one();
 | 
			
		||||
				let u_two = Self::from(2);
 | 
			
		||||
				let mut y = u_one;
 | 
			
		||||
				let mut n = expon;
 | 
			
		||||
				let mut x = self;
 | 
			
		||||
				while n > u_one {
 | 
			
		||||
					if is_even(&n) {
 | 
			
		||||
						x = x * x;
 | 
			
		||||
						n = n / u_two;
 | 
			
		||||
						n = n >> 1;
 | 
			
		||||
					} else {
 | 
			
		||||
						y = x * y;
 | 
			
		||||
						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
 | 
			
		||||
@ -713,13 +714,11 @@ macro_rules! construct_uint {
 | 
			
		||||
			/// Fast exponentation by squaring
 | 
			
		||||
			/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
 | 
			
		||||
			fn overflowing_pow(self, expon: Self) -> (Self, bool) {
 | 
			
		||||
				if expon == Self::zero() {
 | 
			
		||||
					return (Self::one(), false)
 | 
			
		||||
				}
 | 
			
		||||
				if expon.is_zero() { return (Self::one(), false) }
 | 
			
		||||
 | 
			
		||||
				let is_even = |x : &Self| x.low_u64() & 1 == 0;
 | 
			
		||||
 | 
			
		||||
				let u_one = Self::one();
 | 
			
		||||
				let u_two = Self::from(2);
 | 
			
		||||
				let mut y = u_one;
 | 
			
		||||
				let mut n = expon;
 | 
			
		||||
				let mut x = self;
 | 
			
		||||
@ -728,11 +727,11 @@ macro_rules! construct_uint {
 | 
			
		||||
				while n > u_one {
 | 
			
		||||
					if is_even(&n) {
 | 
			
		||||
						x = overflowing!(x.overflowing_mul(x), overflow);
 | 
			
		||||
						n = n / u_two;
 | 
			
		||||
						n = n >> 1;
 | 
			
		||||
					} else {
 | 
			
		||||
						y = overflowing!(x.overflowing_mul(y), 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);
 | 
			
		||||
@ -1068,7 +1067,7 @@ macro_rules! construct_uint {
 | 
			
		||||
 | 
			
		||||
		impl fmt::Display for $name {
 | 
			
		||||
			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
			
		||||
				if *self == $name::zero() {
 | 
			
		||||
				if self.is_zero() {
 | 
			
		||||
					return write!(f, "0");
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@ -1076,7 +1075,7 @@ macro_rules! construct_uint {
 | 
			
		||||
				let mut current = *self;
 | 
			
		||||
				let ten = $name::from(10);
 | 
			
		||||
 | 
			
		||||
				while current != $name::zero() {
 | 
			
		||||
				while !current.is_zero() {
 | 
			
		||||
					s = format!("{}{}", (current % ten).low_u32(), s);
 | 
			
		||||
					current = current / ten;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user