Created
March 19, 2011 23:04
-
-
Save dmitric/877891 to your computer and use it in GitHub Desktop.
Some useful bit arithmetic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#addition, full adder style | |
def add(a,b): | |
if a == 0: | |
return b | |
elif b == 0: | |
return a | |
summed = a^b | |
carry = (a&b) << 1 | |
return add(summed,carry) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#recursive solution | |
def is_a_power_of_two_recursive(n): | |
if n==1: return True | |
if n==0 or n%2 != 0 : return False | |
return is_a_power_of_two_recursive(n/2) | |
#bit arithmetic solution | |
def is_a_power_of_two(n): | |
return n != 0 and (n & (n-1)) == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#returns the floor of the log2 of n | |
def log2(n): | |
i = -1 | |
while n > 0: | |
n = n >> 1 | |
i += 1 | |
return i |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def multiply(a,b): | |
#check if we have a zero in the params, if we do, just return 0 | |
if a == 0 or b == 0: | |
return 0 | |
#if any of the params are 1, just return the other | |
if a==1: | |
return b | |
elif b == 1: | |
return a | |
#now we perform optimizations for numbers that are powers of 2 | |
#we always perform the shift using log2(b) if b is a power of 2, so if a is the power of 2 | |
#swap a and b them and mark that we know its a power of 2 | |
a_is_pow2 = False | |
if(is_a_power_of_two(a)): | |
a,b = b,a | |
a_is_pow2 = True | |
if(a_is_pow2 or is_a_power_of_two(b)): | |
return a << log2(b) | |
else: | |
#we want to iterate as few times as possible, so add the larger | |
#number together by the smaller number of times | |
add_this_many_times,add_this = sorted([a,b]) | |
sum = add_this | |
for i in xrange(1,add_this_many_times): | |
sum = add(add_this,sum) | |
return sum | |
assert(multiply(3,5) == 15) | |
assert(multiply(4,1) == 4) | |
assert(multiply(67,2) == 134) | |
assert(multiply(10,10) == 100) | |
assert(multiply(4,10) == 40) | |
assert(multiply(1024,2**4) == 16384) | |
assert(multiply(2**6,2**0) == 64) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment