In the languages I have tested, - (x div y )
is not equal to -x div y
; I have tested //
in Python, /
in Ruby, div
in Perl 6; C has a similar behavior.
That behavior is usually according to spec, since div
is usually defined as the rounding down of the result of the division, however it does not make a lot of sense from the arithmetic point of view, since it makes div
behave in a different way depending on the sign, and it causes confusion such as this post on how it is done in Python.
Is there some specific rationale behind this design decision, or is just div
defined that way from scratch? Apparently Guido van Rossum uses a coherency argument in a blog post that explains how it is done in Python, but you can have coherency also if you choose to round up.
(Inspired by this question by PMurias in the #perl6 IRC channel)
If the divisor and dividend have the same sign then the result is zero or positive. If the divisor and dividend have opposite signs then the result is zero or negative. If the division is inexact then the quotient is rounded towards zero. That is, up if it is negative, and down if it is positive.
The % (integer divide) operator divides two numbers and returns the integer part of the result. The result returned is defined to be that which would result from repeatedly subtracting the divisor from the dividend while the dividend is larger than the divisor.
Yes, the result is always truncated towards zero. It will round towards the smallest absolute value.
Ideally, we would like to have two operations div
and mod
, satisfying, for each b>0
:
(a div b) * b + (a mod b) = a
0 <= (a mod b) < b
(-a) div b = -(a div b)
This is, however, a mathematical impossibility. If all the above were true, we would have
1 div 2 = 0 1 mod 2 = 1
since this is the unique integer solution to (1) and (2). Hence, we would also have, by (3),
0 = -0 = -(1 div 2) = (-1) div 2
which, by (1), implies
-1 = ((-1) div 2) * 2 + ((-1) mod 2) = 0 * 2 + ((-1) mod 2) = (-1) mod 2
making (-1) mod 2 < 0
which contradicts (2).
Hence, we need to give up some property among (1), (2), and (3).
Some programming languages give up (3), and make div
round down (Python, Ruby).
In some (rare) cases the language offers multiple division operators. For instance, in Haskell we have div,mod
satisfying only (1) and (2), similarly to Python, and we also have quot,rem
satisfying only (1) and (3). The latter pair of operators rounds division towards zero, at the price of returning negative remainders, e.g., we have (-1) `quot` 2 = 0
and (-1) `rem` 2 = (-1)
.
C# also gives up (2), and allows %
to return a negative remainder. Coherently, integer division rounds towards zero. Java, Scala, Pascal, and C, starting from C99, also adopt this strategy.
Floating-point operations are defined by IEEE754 with numeric applications in mind and, by default, round to the nearest representable value in a very strictly-defined manner.
Integer operations in computers are not defined by general international standards. The operations granted by languages (especially those of the C family) tend to follow whatever the underlying computer provides. Some languages define certain operations more robustly than others, but to avoid excessively difficult or slow implementations on the available (and popular) computers of their time, will choose a definition that follows its behaviour quite closely.
For this reason, integer operations tend to wrap around on overflow (for addition, multiplication, and shifting-left), and round towards negative infinity when producing an inexact result (for division, and shifting-right). Both of these are simple truncation at their respective end of the integer in two's-complement binary arithmetic; the simplest way to handle a corner-case.
Other answers discuss the relationship with the remainder or modulus operator that a language might provide alongside division. Unfortunately they have it backwards. Remainder depends on the definition of division, not the other way around, while modulus can be defined independently of division - if both arguments happen to be positive and division rounds down, they work out to be the same, so people rarely notice.
Most modern languages provide either a remainder operator or a modulus operator, rarely both. A library function may provide the other operation for people who care about the difference, which is that remainder retains the sign of the dividend, while modulus retains the sign of the divisor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With