Skip to content

Commit d84a5ae

Browse files
committed
gh-75204: Clarify int division programming faq
Explain the alternative choices for int division (//) and modulo (i % j) sign determination. Mention that some languages choose truncation and 'i' determination. Justify Python's choice of flooring and 'j' determination.
1 parent 0ef8d47 commit d84a5ae

File tree

1 file changed

+17
-17
lines changed

1 file changed

+17
-17
lines changed

Doc/faq/programming.rst

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -825,23 +825,23 @@ or uppercase. For example, in the Python interpreter::
825825
178
826826

827827

828-
Why does -22 // 10 return -3?
829-
-----------------------------
830-
831-
It's primarily driven by the desire that ``i % j`` have the same sign as ``j``.
832-
If you want that, and also want::
833-
834-
i == (i // j) * j + (i % j)
835-
836-
then integer division has to return the floor. C also requires that identity to
837-
hold, and then compilers that truncate ``i // j`` need to make ``i % j`` have
838-
the same sign as ``i``.
839-
840-
There are few real use cases for ``i % j`` when ``j`` is negative. When ``j``
841-
is positive, there are many, and in virtually all of them it's more useful for
842-
``i % j`` to be ``>= 0``. If the clock says 10 now, what did it say 200 hours
843-
ago? ``-190 % 12 == 2`` is useful; ``-190 % 12 == -10`` is a bug waiting to
844-
bite.
828+
Why does -22 // 10 return -3 instead of -2?
829+
-------------------------------------------
830+
831+
A non-integral float, such as ``x = -22 / 10``, can be converted to an int
832+
with either :meth:`math.trunc` or :meth:`math.floor`, giving -2 or -3.
833+
Maintaining the desired invariant ``i == (i // j) * j + (i % j)`` requires
834+
that the choice for integer division (`//`) match the choice for which of
835+
``i`` or ``j`` determines the sign of ``i % j``. For -22 and 10, ``-2*10 + (-2) ==
836+
-3*10 + 8 == -22``. Some languages choose truncation for int division
837+
and hence modulo sign determination by ``i``.
838+
839+
Python chose floor division primarily to make ``i % j`` have the same sign
840+
as ``j``. There are few real use cases for ``i % j`` when ``j`` is negative,
841+
but many for positive ``j``, and in nearly all of them it is
842+
more useful for ``i % j`` to be ``>= 0``. If a clock says 10 now, what did it
843+
say 200 hours ago? ``-190 % 12 == 2`` is useful. Making ``-190 % 12`` be ``-10``
844+
would have often been a bug waiting to happen.
845845

846846

847847
How do I get int literal attribute instead of SyntaxError?

0 commit comments

Comments
 (0)