Reputation: 53
I have written a python program to convert numbers from any positive integer base to another.
print("Base Converter")
from math import log
print("This converter uses 0-9, followed by A-Z, followed by a-z, giving it individual characters from 0 - 61.")
print("If there are digits greater than 61, each digit will be placed in a pair of vertical lines, eg. 4|A|c|X|63|2|H|144|H.")
def BaseConvert(number, StartBase, EndBase):
try: # Make sure that the parameters are in the right format
n = int(str(StartBase)) + int(str(EndBase))
except ValueError:
return "Bad Base input"
StartBase, EndBase = int(StartBase), int(EndBase)
letters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
number = str(number)
for i in number: # Make sure that all the digits are alphanumeric
if not i.isalnum() and i != "|": # Vertical bars are allowed as they seperate digits greater than 61. Other non alphanumeric characters are not.
return "Bad input"
if "|" in number:
number = number.split("|")
StartLength = len(number) # Initial length of number
total = 0 # This will become the final number
for i in range(StartLength):
n = StartLength - i - 1 # This effectively reverses the order,
Digit = number[n] # going from the last digit in the number (furthest to the right), to the first.
if Digit in letters:
Digit = letters.index(Digit) + 10
try:
Digit = int(Digit)
except ValueError:
return "Bad Number Input"
if Digit > StartBase:
return "Bad start base"
total += int(Digit) * (StartBase ** i)
number = total
if EndBase > 1:
n2 = int(log(number, EndBase)) # Length of result number
elif EndBase == 1:
n2 = number
else:
print("Unable to complete base conversion")
return
total = number
numbers = []
J = ""
for i in range(n2 + 1):
X = int(total/(EndBase ** (n2 - i))) # Starting from the largest place value, divides the original number (Now in base 10) by the place value
if X > 9:
if X < 62:
X = letters[X - 10]
else:
X = str(X)
J = "|"
numbers.append(str(X))
total = total % EndBase ** (n2 - i)
EndNumber = J.join(numbers)
return EndNumber
# Base Conversion Function /\ /\
# User input \/ \/ \/ \/ \/ \/ \/
print("Enter your number, start base and end base. (eg. 101101011, 2, 10) ")
inp = "1"
while inp:
inp = input(">>> ")
while inp.count(",") != 2:
if inp == '':
break
print("Bad input")
inp = input(">>> ")
if inp == '':
break
inp = inp.split(",")
print(BaseConvert(inp[0].strip(), inp[1].strip(), inp[2].strip()))
To check my results were right, I found some base converters online to test against and plugged in large numbers, but noticed that different calculators gave different results.
I'm pretty sure my program is correct, I'm not definitely sure but I've done a couple of manual conversions and they compared well to the program, but why are these calculators getting different values?
Upvotes: 1
Views: 123
Reputation: 4465
The site that gives the decimal number to end in many 0s probably just ran out of memory or used a language or algorithm that doesn't work too well with big numbers. Keep in mind that simply the first B
in base 36 is already 4084512220202252076284091826176
in base 10. Given that websites are accessed by many people they have to manage their resources carefully to make sure people don't experience latency. That site most likely just limited the amount of memory each calculation can use.
Result from my own base converter program:
Ruby Base Converter
Convert from base: 36
Number in base 36: BIGNUMBERTESTEXAMPLE
Convert to base: 10
Base 36: BIGNUMBERTESTEXAMPLE
Base 10: 4274945873844657616917501294866
My result matches the first one.
Upvotes: 1