Binary to Decimal
You get a string s that writes a non-negative number in binary, using only the characters 0 and 1. Return the value of that number as an ordinary integer. The string has no leading zeros, except for the number zero, which is the single character 0.
Function
- sstring
- the binary digits of the number
- Returnsinteger
- the value of s as an integer
Constraints
1 ≤ s.length ≤ 31scontains only0and1.sstarts with1, unlesssis"0".- Read the digits yourself instead of calling a built-in base conversion.
Examples
- Input
- s = "1101"
- Output
- 13
- Explanation
- Reading from the right, the places are worth 1, 2, 4 and 8.
1101has 1s in the places for 8, 4 and 1, and8 + 4 + 1 = 13.
- Input
- s = "0"
- Output
- 0
- Explanation
- A single
0has no 1 in any place, so its value is0.
- Input
- s = "10000000"
- Output
- 128
- Explanation
- The only 1 has seven 0s to its right, so it sits in the place worth
2^7 = 128.
Follow-up
Can you read a number written in any base from 2 to 16 with the same loop, where the letters a to f stand for the digits 10 to 15?
Hints
Open them one at a time. Each one gives away a little more.
In decimal, the digits of
347are worth 300, 40 and 7. What is each binary digit worth?The rightmost binary digit is worth 1, and each step to the left doubles the place value: 1, 2, 4, 8 and so on. The number is the sum of the place values that hold a 1.
You can avoid computing powers: read from the left, and for each digit set the running value to twice itself plus that digit. After the last digit, the running value is the answer.
Solution
Each binary digit stands for a power of two, set by how far it sits from the right end. You can add those powers from the right, or read from the left and double the value at every step: the same loop that reads decimal text, with 2 in place of 10.
Add place values from the right
Intuition
The rightmost digit is worth 1, and each place to the left is worth twice the one before it. The number is the sum of the place values that hold a 1, so walk from the last character to the first, keep the current place value in power, and add it at every 1.
Every digit is visited once: O(n) time and two numbers of memory.
Algorithm
- Set
total = 0andpower = 1. - Walk the string from its last character to its first.
- If the character is
1, addpowertototal. - Double
powerbefore moving one place left. - Return
total.
def toDecimal(s):
total = 0
power = 1 # the place value of the rightmost digit
for i in range(len(s) - 1, -1, -1):
if s[i] == "1":
total += power
power *= 2
return totalDouble and add from the left
Intuition
Keep value, the number spelled by the digits read so far. Appending one more digit shifts every earlier digit one place left, which doubles its worth, and then adds the new digit: value = value * 2 + digit. For 1101, value goes 1, 3, 6, 13.
Each prefix of the string is a smaller binary number and the loop holds exactly that number, so after the last digit it holds the answer. The value never exceeds the final answer, so a 32-bit integer is enough for 31 digits. No power is ever computed.
Algorithm
- Set
value = 0. - For each character from left to right, turn it into a digit by subtracting the code of
'0'. - Set
value = value * 2 + digit. - Return
value.
def toDecimal(s):
value = 0
for ch in s:
# Shift the digits read so far one place left, then add the new one.
value = value * 2 + (ord(ch) - ord("0"))
return value
Pitfalls and edge cases
- Giving the leftmost digit the place value 1.
1101then reads as 11. - Adding the character instead of the digit. In many languages
'1'is the number 49, sovalue * 2 + '1'is far too large; subtract'0'first. - Doubling
powerafter the last digit in a 32-bit integer. For a 31-digit string it reaches2^31, which wraps around or crashes; keep it in 64 bits or skip the last doubling.
Frequently asked questions3
How do you convert binary to decimal?
Give each digit a place value, a power of two that starts at 1 on the right end, and add the place values of the digits that are 1. Or read the digits from the left and set value = value * 2 + digit at each step.
What is the time complexity of converting binary to decimal?
Both loops visit each of the n characters once, so they take O(n) time. They keep only one or two numbers, which is O(1) extra space.
Can you convert binary to decimal with bit shifts?
Yes. value = (value << 1) | digit does the same as value * 2 + digit: the shift doubles the value and the or sets the lowest bit. The arithmetic form also works for bases other than 2.
Similar problems
Problems that use the same ideas. Solving two or three of them is what makes a pattern stick.
def toDecimal(s):
# Write code hereTest #1
Test #2
Test #3
Argument
s = "1101"
Expected Output
13