What is the reason for difference between integer division and float to int conversion in python?

Consistency.

You'll need to follow some very basic and seemingly irrelevant explanations to understand it.

In school you have learned division with a remainder. And you have done calculations like this:

8 ÷ 4 = 2 R 0
7 ÷ 4 = 1 R 3
6 ÷ 4 = 1 R 2
5 ÷ 4 = 1 R 1
4 ÷ 4 = 1 R 0
3 ÷ 4 = 0 R 3
2 ÷ 4 = 0 R 2
1 ÷ 4 = 0 R 1
0 ÷ 4 = 0 R 0
        ^------ This is the result of x // 4
            ^-- This is the result of x % 4 (modulo)

Later, you have learned divisions for real numbers:

8 ÷ 4 = 2.0
7 ÷ 4 = 1.75
6 ÷ 4 = 1.5
5 ÷ 4 = 1.25
4 ÷ 4 = 1.0
3 ÷ 4 = 0.75
2 ÷ 4 = 0.5
1 ÷ 4 = 0.25
0 ÷ 4 = 0.0
        ^--- Note that the number in front of the . is int(x/4)

Until this point, you might believe that x // 4 and int(x/4) always give the same result. That's your current understanding of the situation.

However, have a look what happens in the integer division: the number behind R cycles from 3, 2, 1 to 0 and then restarts: 3, 2, 1, 0. The number in front of the R decreses every 4th step.

So, how will it go on?

 8 ÷ 4 =  2 R 0
 7 ÷ 4 =  1 R 3
 6 ÷ 4 =  1 R 2
 5 ÷ 4 =  1 R 1
 4 ÷ 4 =  1 R 0
 3 ÷ 4 =  0 R 3
 2 ÷ 4 =  0 R 2
 1 ÷ 4 =  0 R 1
 0 ÷ 4 =  0 R 0
-1 ÷ 4 = -1 R 3
         ^------ We have to decrease now, because we already have 0 four times
              ^-- We have to restart the cycle at 3

At the same time, the real number division gives us:

-1 ÷ 4 = -0.25
          ^----- There is still a 0 in front of the .

That's why -1 // 4 gives -1 but int(-1/4) gives 0.

Is there any motivation for the differences between the functions?

Well, they serve different purposes: // is part of an integer calculation with remainders and int() gives you the part in front of the . of a real number operation.

You decide what you want to calculate, then you decide which operator to use in Python to get the correct result.

Good question. Keep on learning.


I would say that your observation that those 2 operations should be intuitively similar is expected since on positive numbers they behave identically. But if you look at their origins (one comes from mathematics and the other from computer science) then it makes more sense their different behavior.

You can look behind there concepts:

  • Floor division aka the floor function applied to the math division
  • Type conversion/Type casting

==================================================================

I)Floor division aka the floor function applied to the math division

The floor function is a very well established concept in mathematics.

From mathworld.wolfram:

The floor function |_ x_ |, also called the greatest integer function or integer value (Spanier and Oldham 1987), gives the largest integer less than or equal to x. The name and symbol for the floor function were coined by K. E. Iverson (Graham et al. 1994)

So floor division is nothing more than floor function applied to the math division. The behavior is very clear, "mathematically precise".

II)Type conversion/Type casting

From wikipedia:

In computer science, type conversion, type casting, type coercion and type juggling are different ways of changing an expression from one data type to another.

In most of the programming languages, the casting form float to integer is applied by rounding rule (so there is a convention) :

  • Round toward 0 – directed rounding towards zero (also known as truncation)

Rounding rule according to IEEE 754.


So, in other words, the reason for the difference between integer division and float to int conversion in python is a mathematical one, here are some thoughts from Guido van Rossum (I guess I do not have to introduce him :D) (from the blog The history of Python, article "Why Python's Integer Division Floors")

This disturbs some people, but there is a good mathematical reason. The integer division operation (//) and its sibling, the modulo operation (%), go together and satisfy a nice mathematical relationship (all variables are integers):

a/b = q with remainder r

such that

b*q + r = a and 0 <= r < b

(assuming a and b are >= 0).