Issue
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?
Solution
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
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.