My decimal to binary converter gives wrong results with bigger numbers

Question:

I’ve made a really simple decimal to binary converter, everything seems to work fine but when given a big number it spits out results that are way different from results from another online converters. I wonder why is that?

here’s my code:

def main():
    numberstr = input("Number in decimal > ")
    number = int(numberstr)
    result = ""
    while number >= 1 == True:
        if (number % 2) == 1:
            remainder = "1"
            result = remainder + result
            if number == 1:
                number = 0
            else:
                number = number - 1
                number = number / 2
                number = int(number) 
                #^^^ this line is for getting rid of the float that comes from dividing.

        elif (number % 2) == 0:
            remainder = "0"
            result = remainder + result
            number = number / 2
            number = int(number)
        
    print(numberstr, "in binary is:", result)
  
main()

for example feeding it this number: 987654321987654321
gives out this result: 110110110100110110100101111101111110111101000001001010000001
While online converters (namely rapidtables.com and binaryhexconverter.com ) both give out this: 110110110100110110100101111101111110111101000001001010110001

For comparing:
110110110100110110100101111101111110111101000001001010000001 – my code
110110110100110110100101111101111110111101000001001010110001
It seems that to some point it does the math right, but then it messes up for some reason.
Any ideas on what might be causing it?

Asked By: SpizCode

||

Answers:

The issue is with division. When you do number / 2 it becomes a float. When you are working with large numbers, floats will loose precision.

You need to use floor division number // 2, which gives the quotient of number divided by 2, discarding the remainder. Once you use floor division or integer division, you no longer need number=number - 1, or number = int(number).

def main():
    numberstr = input("Number in decimal > ")
    number = int(numberstr)
    result = ""
    while number >= 1 == True:
        if (number % 2) == 1:
            remainder = "1"
            result = remainder + result
            if number == 1:
                number = 0
            else:
                number = number // 2
                #^^^ this line is for getting rid of the float that comes from dividing.

        elif (number % 2) == 0:
            remainder = "0"
            result = remainder + result
            number = number // 2
        
    print(numberstr, "in binary is:", result)
  
main()

This will give you the correct result:

110110110100110110100101111101111110111101000001001010110001

Alternatively,

Another good way of doing integer division by 2, i.e. discard the last binary digit, is to use bit shift operator >>, this shifts the binary representation to the right by 1 bit and thus removing the last bit, whether it’s 0 or 1.

number = number >> 1

And to get the remainder, another good way is "bitwise and" operator &:

remainder_number = number & 1

Bitwise operations are fast.

So a much shorter version would be

def main():
    numberstr = input("Number in decimal > ")
    number = int(numberstr)
    result = ""
    while number >= 1:
        result = str(number & 1) + result
        number = number >> 1

    print(numberstr, "in binary is:", result)

main()

if-else statements are also slow, avoid them if you can.

Answered By: Tim
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.