import sys
import time


val10 = 0b1100011011000110110001101100011110001101100011011000110110001101
niter = 100000

if len(sys.argv) > 1:
    val10 = int(sys.argv[1], 2)
if len(sys.argv) > 2:
    niter = int(sys.argv[2])


def bit_reverse(val):
    ret = 0
    while 1:
        v0 = val & 0b001    # save the final bit to v0

        ret = ret | v0      # put v0 to the final bit of ret (will be the top digit of ret)
        val = val >> 1      # bit shift for next iteration
        if val == 0:
            break
        else:
            ret = ret << 1  # bit shift ret to left

    return ret

def bit_reverse_nobitop(val):
    ret = 0
    while 1:
        v0 = val % 2        # save the final bit to v0

        ret = ret + v0      # put v0 to the final bit of ret (will be the top digit of ret)
        val = val // 2      # bit shift for next iteration
        if val == 0:
            break
        else:
            ret = ret * 2  # bit shift ret to left

    return ret

def bit_reverse_nobitop2(val):
    ret = 0
    while 1:
        v0 = val % 2   # save the final bit to v0

        ret += v0      # put v0 to the final bit of ret (will be the top digit of ret)
        val //= 2      # bit shift for next iteration
        if val == 0:
            break
        else:
            ret *= 2  # bit shift ret to left

    return ret


print("")
print("Base 10 input: ", val10)
print("Base 2: {:b}".format(val10))

print("")
print("by bitwise operation")
vrev = bit_reverse(val10)
print("reversed in Base 10 =", vrev)
print("         in Base 2  = {:b}".format(vrev))
print("without bitwise operation")
vrev = bit_reverse_nobitop(val10)
print("reversed in Base 10 =", vrev)
print("         in Base 2  = {:b}".format(vrev))

print("")
print("Time for {} iterations".format(niter))

st = time.time()
for i in range(niter):
    bit_reverse(val10)
et = time.time()
print("by bitwise operation     : {} s".format(et - st))

st = time.time()
[bit_reverse(val10) for i in range(niter)]
et = time.time()
print("by bitwise operation (list incl): {} s".format(et - st))

st = time.time()
for i in range(niter):
    bit_reverse_nobitop(val10)
et = time.time()
print("without bitwise operation: {} s".format(et - st))

st = time.time()
for i in range(niter):
    bit_reverse_nobitop2(val10)
et = time.time()
print("without bitwise operation #2: {} s".format(et - st))

print("")

