Search code examples
pythonmathprimesfloorfloor-division

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 ?


Solution

  • 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
    >>>