Take for example a string s="556852144786"
that represents the decimal number n=556852144786
. Is there a direct algorithm to transform it to s1="1000000110100110..."
where 1000000110100110...
is the binary representation of n
?

- 29,088
- 9
- 83
- 120

- 1
1 Answers
I assume that you're looking for an algorithm that operates directly on strings, instead of converting to whatever integers are supported by the target language and using those?
There are various ways to do this. Here are two, though if you squint hard enough, they're almost the same algorithm.
Method 1: repeatedly divide the decimal string by two
In this method, we repeatedly divide the original decimal string by 2 (using decimal arithmetic), and keep track of the remainders: those remainders give you the bits of the result in reverse order.
Here's what that algorithm looks like, in Python. It's missing definitions of is_nonzero
and divide_by_two
. We'll provide those in a moment.
def dec_to_bin(s):
"""
Convert decimal string s to binary, using only string operations.
"""
bits = ""
while is_nonzero(s):
s, bit = divide_by_two(s)
bits += bit
# The above builds up the binary string in reverse.
return bits[::-1]
The algorithm generates the bits in reverse order, so we need a final reverse to give the resulting binary string.
The divide_by_two
function takes a decimal string s
and returns a new decimal string representing the quotient s / 2
, along with the remainder. The remainder is a single bit, again represented as a string - either "0"
or "1"
. It follows the usual digit-by-digit school-taught left-to-right division method: each step involves dividing a single digit, along with the carry brought in from the previous step, by two. Here's that function:
def divide_by_two(s):
"""
Divide the number represented by the decimal string s by 2,
giving a new decimal string quotient and a remainder bit.
"""
quotient = ""
bit = "0"
for digit in s:
quotient_digit, bit = divide_digit_by_two(bit, digit)
quotient += quotient_digit
return quotient, bit
We're left needing to define divide_digit_by_two
, which takes a single digit plus a tens carry bit, and divides by two to get a digit quotient and a single-bit remainder. At this point, all inputs and outputs are strings of length one. Here we cheat and use integer arithmetic, but there are only 20 possible different combinations of inputs, so we could easily have used a lookup table instead.
def divide_digit_by_two(bit, digit):
"""
Divide a single digit (with tens carry) by two, giving
a digit quotient and a single bit remainder.
"""
digit, bit = divmod(int(bit) * 10 + int(digit), 2)
return str(digit), str(bit)
You can think of divide_digit_by_two
as a primitive arithmetic operation that swaps two digits in different bases: it converts a nonnegative integer smaller than 20
represented in the form 10 * bit + digit
into the same value represented in the form 2 * digit + bit
.
We're still missing one definition: that of is_nonzero
. A decimal string represents zero if and only if it consists entirely of zeros. Here's a quick Python test for that.
def is_nonzero(s):
"""
Determine whether the decimal string s represents zero or not.
"""
return s.strip('0') != ''
And now that we have all the bits in place, we can test:
>>> dec_to_bin("18")
'10010'
>>> dec_to_bin("556852144786")
'1000000110100110111110010110101010010010'
>>> format(556852144786, 'b') # For comparison
'1000000110100110111110010110101010010010'
Method 2: repeatedly multiply the binary string by 10
Here's a variant on the first method: instead of repeated divisions, we process the incoming decimal string digit by digit (from left to right). We start with an empty binary string representing the value 0
, and each time we process a digit we multiply by 10 (in the binary representation) and add the value represented by that digit. As before, it's most convenient to build up the binary string in little-endian order (least-significant bit first) and then reverse at the end to get the traditional big-endian representation. Here's the top-level function:
def dec_to_bin2(s):
"""
Convert decimal string s to binary, using only string operations.
Digit-by-digit variant.
"""
bits = ""
for digit in s:
bits = times_10_plus(bits, digit)
return bits[::-1]
The job of the times_10_plus
function is to take a binary string and a digit, and produce a new binary string representing the result of multiplying the value of the original by ten, and adding the value of the binary digit. It looks like this:
def times_10_plus(bits, digit):
"""
Multiply the value represented by a binary string by 10, add a digit,
and return the result as a binary string.
"""
result_bits = ""
for bit in bits:
digit, result_bit = divide_digit_by_two(bit, digit)
result_bits += result_bit
while digit != "0":
digit, result_bit = divide_digit_by_two("0", digit)
result_bits += result_bit
return result_bits
Note that we're using exactly the same arithmetic primitive divide_digit_by_two
as before, but now we're thinking of it slightly differently: it's multiplying a single bit by ten, adding a carry digit, and turning that into a new bit (the least significant bit of the result) along with a new carry digit.
Efficiency notes
In the interests of clarity, I've left some Python-level inefficiencies. In particular, when building up the strings, it would be more efficient to build a list of bits or digits and then concatenate with a str.join
operation right at the end. Also note that depending on the implementation language, it may make more sense to modify either the digit string or the bit string in-place instead of generating a new string at each step. I leave the necessary changes to you.

- 29,088
- 9
- 83
- 120