Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behaviour of division in python

I'm trying to solve this problem in hackerrank. At some point I have to check if a number divides n(given input) or not.

This code works perfectly well except one test case(not an issue):

if __name__ == '__main__':
    tc = int(input().strip())
    for i_tc in range(tc):
        n = int(input().strip())
        while n % 2 == 0 and n is not 0:
            n >>= 1
        last = 0



        for i in range(3, int(n ** 0.5), 2):
            while n % i == 0 and n > 0:
                last = n
                n = n // i        # Concentrate here


        print(n if n > 2 else last)

Now you can see that I'm dividing the number only when i is a factor of n.For example if the numbers be i = 2 and n = 4 then n / 2 and n // 2 doesn't make any difference right.

But when I use the below code all test cases are getting failed:

if __name__ == '__main__':
    tc = int(input().strip())
    for i_tc in range(tc):
        n = int(input().strip())
        while n % 2 == 0 and n is not 0:
            n >>= 1
        last = 0
        for i in range(3, int(n ** 0.5), 2):
            while n % i == 0 and n > 0:
                last = n
                n = n / i      # Notice this is not //
        print(n if n > 2 else last)

This is not the first time.Even for this problem I faced the same thing.For this problem I have to only divide by 2 so I used right shift operator to get rid of this.But here I can't do any thing since right shift can't help me.

Why is this happening ? If the numbers are small I can't see any difference but as the number becomes larger it is somehow behaving differently.

It is not even intuitive to use // when / fails. What is the reason for this ?

like image 404
Bharat Avatar asked Oct 03 '17 13:10

Bharat


1 Answers

The main reason of the difference between n // i and n / i given that n and i are of type int and n % i == 0 is that

  1. the type of n // i is still int whereas the type of n / i is float and
  2. integers in Python have unlimited precision whereas the precision of floats is limited.

Therefore, if the value of n // i is outside the range that is accurately representable by the python float type, then it will be not equal to the computed value of n / i.

Illustration:

>>> (10**16-2)/2 == (10**16-2)//2
True
>>> (10**17-2)/2 == (10**17-2)//2
False
>>> int((10**17-2)//2)
49999999999999999
>>> int((10**17-2)/2)
50000000000000000
>>> 
like image 67
Leon Avatar answered Sep 26 '22 06:09

Leon