I\'m trying to make a program to convert a number in any base to another base of the user\'s choice. The code I have so far goes like this:
innitvar = float(
Just a Student, slow down with the idea of what you need. You may not need what you think you need.
Start at the beginning: the user inputs a number. The user inputs a base. These are both Strings. Say the base is 12, and the number is 1AB3. So you have a '1' in the 12^3 place, an 'A' in the 12^2 place, a 'B' in 12^1, and a '3' in the 12^0 (ones) place. If you want this number in base 10, you're going to need to add some numbers together.
Specifically, you need to add 1*12^3 + 10*12^2 + 11*12^1 + 3*12^0. Notice something here: you have 3,2,1,0. Which corresponds nicely to the LENGTH of the input string 1AB3. So probably a for
loop would be helpful here. The user doesn't input an integer, they input a string. So you need the characters from the string, not the digits from the number.
How do you know what the symbols 'A' and 'C' represent in decimal notation? Look at the answer from Noctis Skytower!
So your first task is to figure out how to ITERATE THROUGH A STRING. Your second task is to figure out how to use the individual character values from your string to access the dictionary in Noctis Skytower's answer, and your third task is to figure out how to write a loop that takes advantage of that information.
I need to multiply the leftmost digit in the initial number by its innitial base, and then add the next digit to the right, and then repeat until I hit the rightmost digit.
So you need to get digits. In a list.
Hint 1: Use divmod()
function to break a number into digits. Divide by 10 to get decimal digits.
Hint 2: While n > 0: you can use divmod()
to get a quotient and a remainder. If you save the remainder in the list, and use the quotient as the new value of n your number gets smaller until what's left is zero and you're done.
Hint 3: Your digits arrive in right-to-left order. Use reverse
to switch the order of the list of this bothers you. Or create the list by using insert(0,digit)
.
Now that you have the digits. In a list. You can iterate through the list.
Try the for
statement on for size.
You might need to use a "multiple and add" loop. total = total * new_base + next_digit
is the way the body of the loop often looks.
This should be the first half of the answer to your problem. Can you figure out how to convert to a base?
# Create a symbol-to-value table.
SY2VA = {'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'A': 10,
'B': 11,
'C': 12,
'D': 13,
'E': 14,
'F': 15,
'G': 16,
'H': 17,
'I': 18,
'J': 19,
'K': 20,
'L': 21,
'M': 22,
'N': 23,
'O': 24,
'P': 25,
'Q': 26,
'R': 27,
'S': 28,
'T': 29,
'U': 30,
'V': 31,
'W': 32,
'X': 33,
'Y': 34,
'Z': 35,
'a': 36,
'b': 37,
'c': 38,
'd': 39,
'e': 40,
'f': 41,
'g': 42,
'h': 43,
'i': 44,
'j': 45,
'k': 46,
'l': 47,
'm': 48,
'n': 49,
'o': 50,
'p': 51,
'q': 52,
'r': 53,
's': 54,
't': 55,
'u': 56,
'v': 57,
'w': 58,
'x': 59,
'y': 60,
'z': 61,
'!': 62,
'"': 63,
'#': 64,
'$': 65,
'%': 66,
'&': 67,
"'": 68,
'(': 69,
')': 70,
'*': 71,
'+': 72,
',': 73,
'-': 74,
'.': 75,
'/': 76,
':': 77,
';': 78,
'<': 79,
'=': 80,
'>': 81,
'?': 82,
'@': 83,
'[': 84,
'\\': 85,
']': 86,
'^': 87,
'_': 88,
'`': 89,
'{': 90,
'|': 91,
'}': 92,
'~': 93}
# Take a string and base to convert to.
# Allocate space to store your number.
# For each character in your string:
# Ensure character is in your table.
# Find the value of your character.
# Ensure value is within your base.
# Self-multiply your number with the base.
# Self-add your number with the digit's value.
# Return the number.
def str2int(string, base):
integer = 0
for character in string:
assert character in SY2VA, 'Found unknown character!'
value = SY2VA[character]
assert value < base, 'Found digit outside base!'
integer *= base
integer += value
return integer
Here is the second half of the solution. By using these two functions, converting bases is very easy to do.
# Create a value-to-symbol table.
VA2SY = dict(map(reversed, SY2VA.items()))
# Take a integer and base to convert to.
# Create an array to store the digits in.
# While the integer is not zero:
# Divide the integer by the base to:
# (1) Find the "last" digit in your number (value).
# (2) Store remaining number not "chopped" (integer).
# Save the digit in your storage array.
# Return your joined digits after putting them in the right order.
def int2str(integer, base):
array = []
while integer:
integer, value = divmod(integer, base)
array.append(VA2SY[value])
return ''.join(reversed(array))
After putting it all together, you should end up with the program below. Please take time to figure it out!
innitvar = raw_input("Please enter a number: ")
basevar = int(raw_input("Please enter the base that your number is in: "))
convertvar = int(raw_input("Please enter the base that you would like to convert to: "))
# Create a symbol-to-value table.
SY2VA = {'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'A': 10,
'B': 11,
'C': 12,
'D': 13,
'E': 14,
'F': 15,
'G': 16,
'H': 17,
'I': 18,
'J': 19,
'K': 20,
'L': 21,
'M': 22,
'N': 23,
'O': 24,
'P': 25,
'Q': 26,
'R': 27,
'S': 28,
'T': 29,
'U': 30,
'V': 31,
'W': 32,
'X': 33,
'Y': 34,
'Z': 35,
'a': 36,
'b': 37,
'c': 38,
'd': 39,
'e': 40,
'f': 41,
'g': 42,
'h': 43,
'i': 44,
'j': 45,
'k': 46,
'l': 47,
'm': 48,
'n': 49,
'o': 50,
'p': 51,
'q': 52,
'r': 53,
's': 54,
't': 55,
'u': 56,
'v': 57,
'w': 58,
'x': 59,
'y': 60,
'z': 61,
'!': 62,
'"': 63,
'#': 64,
'$': 65,
'%': 66,
'&': 67,
"'": 68,
'(': 69,
')': 70,
'*': 71,
'+': 72,
',': 73,
'-': 74,
'.': 75,
'/': 76,
':': 77,
';': 78,
'<': 79,
'=': 80,
'>': 81,
'?': 82,
'@': 83,
'[': 84,
'\\': 85,
']': 86,
'^': 87,
'_': 88,
'`': 89,
'{': 90,
'|': 91,
'}': 92,
'~': 93}
# Take a string and base to convert to.
# Allocate space to store your number.
# For each character in your string:
# Ensure character is in your table.
# Find the value of your character.
# Ensure value is within your base.
# Self-multiply your number with the base.
# Self-add your number with the digit's value.
# Return the number.
integer = 0
for character in innitvar:
assert character in SY2VA, 'Found unknown character!'
value = SY2VA[character]
assert value < basevar, 'Found digit outside base!'
integer *= basevar
integer += value
# Create a value-to-symbol table.
VA2SY = dict(map(reversed, SY2VA.items()))
# Take a integer and base to convert to.
# Create an array to store the digits in.
# While the integer is not zero:
# Divide the integer by the base to:
# (1) Find the "last" digit in your number (value).
# (2) Store remaining number not "chopped" (integer).
# Save the digit in your storage array.
# Return your joined digits after putting them in the right order.
array = []
while integer:
integer, value = divmod(integer, convertvar)
array.append(VA2SY[value])
answer = ''.join(reversed(array))
# Display the results of the calculations.
print answer
You need to write two functions. In Scheme (since I know Scheme much better than Python :-P), those two functions are called string->number
and number->string
, though of course you can name them whatever you like.
Each of those functions needs to take a base parameter to do the conversion in. You can make it default to 10, if you like.
Once you implement each of those successfully, the rest is a piece of cake.
Test cases for you:
assert str2num('1234', 10) == 1234
assert str2num('1234', 16) == 0x1234
assert num2str(1234, 10) == '1234'
assert num2str(1234, 16) == '4d2'
assert num2str(0x1234, 16) == '1234'
int() can convert strings from any base between 2 and 36. If you need a wider range than that then create a string containing the digits and use the index() method to get the value.
I came here looking for shortcuts but looks like none exist. So here are the long methods I have found. This answer is based on an answer at Quora and also related to other answers here.
The easiest way(probably) is to convert any number from a base b1 to b2 is to convert b1→Decimal→b2.
A number in the base b1 can be treated like a polynomial in the base b1,
ie, a 4-digit number abcd = d*(b1^0)+c*(b1^1)+b*(b1^2)+a*(b1^3)
Eg., 123(Decimal) = 3*(10^0)+2*(10^1)+1*(10^2)
So, to convert from any base to Decimal, find the sum of all [digit*(base^power)]
(where power is 0 to [NumOfDigits-1]) in the reverse order of the digits.
For this, treat the number as a string
and iterate through it using a for
loop.
So, the input should be a string
and the op an int
.
The next step is to convert a Decimal number D to base b2.
Divide D/b2, the remainder is the rightmost digit. Divide the quotient by b2, the remainder this time is the next rightmost digit. Repeat this cycle until the quotient is 0.
Eg.,
8(Dec) to Binary:
8/2=4; 8%2=0
4/2=2; 4%2=0
2/2=1; 2%2=0
1/2=0; 1%2=1
8(Dec)=1000(Bin)
This is done by treating the output number as a string, and reversing the string after concatenating all the digits to it. (See above: '0' + '0' + '0' + '1' ='0001'
, reverse it