Integer division of negative numbers

It may be surprising that there is a difference in integer division between Python and other languages like Swift, C++ and Java when it comes to negative numbers.

The reason for this difference is because "Integer division" is not a well-defined concept and the specification for each language can choose truncation towards zero or negative infinity as its defined result for the operation. Guido van Rossum wrote a post on the reasoning behind the decision in Python - Why Python's Integer Division Floors


Division and Integer Division

The following example shows that integer division between two numbers does not yield the same absolute value when one of the numbers is negative. The results show that the float division is identical except for the negative sign, while the integer division results are different.

1for i in range(1,12):
2    print(f"{11//i}, {-11//i}, {11/i:.2F} {-11/i:.2F}")

Comparison of integer division with positive and negative numbers in Python

i 11 // i -11 // i 11 / i -11 / i
1 11 -11 11.00 -11.00
2 5 -6 5.50 -5.50
3 3 -4 3.67 -3.67
4 2 -3 2.75 -2.75
5 2 -3 2.20 -2.20
6 1 -2 1.83 -1.83
7 1 -2 1.57 -1.57
8 1 -2 1.38 -1.38
9 1 -2 1.22 -1.22
10 1 -2 1.10 -1.10
11 1 -1 1.00 -1.00

Division and Integer Division results in Swift

Similar code run in Swift yields different results. These match the results for C++.

1for i in 1...11{
2    print("\(i) : \(11/i), \(-11/i), \(11.0/Double(i)), \(-11.0/Double(i))")
3}

Comparison of integer division with positive and negative numbers in Swift

i 11 // i -11 // i 11 / i -11 / i
1 11 -11 11.00 -11.00
2 5 -5 5.50 -5.50
3 3 -3 3.67 -3.67
4 2 -2 2.75 -2.75
5 2 -2 2.20 -2.20
6 1 -1 1.83 -1.83
7 1 -1 1.57 -1.57
8 1 -1 1.38 -1.38
9 1 -1 1.22 -1.22
10 1 -1 1.10 -1.10
11 1 -1 1.00 -1.00


Floor

Take a specific example from above such as 11//4 that results in a value of 2.75. It is easy to assume, when dealing with positive numbers, that the digits after the decimal point are discarded and the integer value returned is the number before the decimal point. This is true for positive numbers, but the same assumption for negative numbers would suggest a result of -2, which is incorrect for Python. Python uses math.floor to determine the integer result and math.floor returns the next integer value towards negative infinity. Other languages truncate the value towards zero and thus return a different result.

It is shown below that both the positive and negative result is ±2.75, but the positive integer result is 2 and the negative integer result is -3.

 1print(11//4)
 2"""
 32
 4"""
 5
 6print(11//-4)
 7"""
 8-3
 9"""
10
11print(11/4)
12"""
132.75
14"""
15
16print(11/-4)
17"""
18-2.75
19"""

In Python math.floor truncates towards negative infinity
In Python math.floor truncates towards negative infinity



Other math functions

It should be noted that converting a double to an integer in Python does truncate towards zero. Rounding a double number with math.round returns the corresponding positive or negative nearest absolute whole number. math.trunc truncates the number towards zero, but math.floor floors towards negative infinity.

 1int(2.75), int(-2.75), int(2.15), int(-2.15)
 2"""
 3(2, -2, 2, -2)
 4"""
 5
 6round(2.75), round(-2.75), round(2.15), round(-2.15)
 7"""
 8(3, -3, 2, -2)
 9"""
10
11math.floor(2.75), math.floor(-2.75), math.floor(2.15), math.floor(-2.15)
12"""
13(2, -3, 2, -3)
14"""
15
16math.trunc(2.75), math.trunc(-2.75), math.trunc(2.15), math.trunc(-2.15)
17"""
18(2, -2, 2, -2)
19"""

Compare floor and truncate functions
Illustrate floor and truncate functions in Python



Conclusion

In Python integer division on negative numbers produces different absolute values than the equivalent integer division on positive numbers. The behavior is consistent within the language and the reason is the use of floor of the result rather than truncation. This may come to light from time to time when adopting an algorithm from on e language to another and discovering discrepancies. If in doubt, test the results of integer division with negative numbers in the language or avoid integer division when dealing with negative numbers.