# [R] Integer division

Richard O'Keefe r@oknz @end|ng |rom gm@||@com
Wed Dec 21 04:44:51 CET 2022

```Lack of consensus:
I should mention Python's // operator, which does
flooring division.
I should mention Common Lisp, where (floor - -),
(ceiling - -), (round - -), and (truncate - -)
all return a quotient and appropriate remainder.
I should mention Smalltalk, where // and \\ are
flooring quotient and remainder and quo: and rem:
are truncating quotient and remainder.
I should give dishonourable mention to certain
programming languages where the quotient and remainder
operators do not actually fit together.

Why the lack of consensus:
It starts with the fact that there wasn't an agreed
*mathematical* definition.  Number theorists, as a
rule, don't care about negative numbers all that much.
To the extent that they do care, x mod y has to go
around in neat cycles, which flooring division does
satisfy and truncating division does not.

It then goes on to early computers which used sign-and-
magnitude or ones-complement representation.  In those
computers, truncating division was the *obvious* thing
to do.  It also had the nice property that
n / (2**k) was the same thing as an arithmetic right
shift by k bits.  And then twos-complement became
popular.  And not only is the twos-complement range
asymmetric (so that x might be representable but -x not)
but arithmetic right shifts aren't the same as truncating
division any more.  Whoops!

And then, although flooring division still made sense for
twos-complement but truncating division didn't really,
new programming languages kept on specifying truncating
division because the programming languages of the 1960s
for the hardware of the 1960s did so.  So new hardware
designers supported the new programming languages without
supporting the *reasons* why truncating division had been
used.

> (-8:7)%%4
[1] 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3

Think about for example histogramming a collection of
integers by their remainders and what would happen with
truncating remainder.

On Tue, 20 Dec 2022 at 19:53, Göran Broström <gb using ehar.se> wrote:

> Thanks Richard,
>
> the "rounding claim" was my mistake (as I replied to Martin), I should
> said "truncates toward zero" as you explain.
>
> However, my point was that these two mathematical functions should be
> defined in the documentation, as you also say. And I was surprised that
> there is no consensus regarding the definition of such elementary
> functions.
>
> Göran
>
> On 2022-12-20 03:01, Richard O'Keefe wrote:
> > The Fortran '08 standard says <<
> > One operand of type integer may be divided by another operand of type
> > integer. Although the mathematical
> > quotient of two integers is not necessarily an integer, Table 7.2
> > specifies that an expression involving the division
> > operator with two operands of type integer is interpreted as an
> > expression of type integer. The result of such an
> > operation is the integer closest to the mathematical quotient and
> > between zero and the mathematical quotient
> > inclusively. >>
> > Another way to say this is that integer division in
> > Fortran TRUNCATES towards zero.  It does not round and
> > never has.
> >
> > C carefully left the behaviour of integer division (/)
> > unspecified, but introduced the div(,) function with the
> > same effect as Fortran (/).  Later versions of the C
> > standard tightened this up, and the C17 standard reads <<
> > The result of the / operator is the quotient from the division of the
> > first operand by the second; the
> > result of the % operator is the remainder. In both operations, if the
> > value of the second operand is
> > zero, the behavior is undefined.
> > When integers are divided, the result of the / operator is the algebraic
> > quotient with any fractional
> > part discarded. 107) If the quotient a/b is representable, the
> > expression (a/b)*b + a%b shall equal a ;
> > otherwise, the behavior of both a/b and a%b is undefined.>>
> >
> > That is, C17 TRUNCATES the result of division towards
> > zero.  I don't know of any C compiler that rounds,
> > certainly gcc does not.
> >
> >
> > The Java 15 Language Specification says
> > << Integer division rounds toward 0. >>
> > which also specified truncating division.
> >
> >
> > The help for ?"%/%" does not say what the result is.
> > Or if it does, I can't find it.  Either way, this is
> > a defect in the documentation.  It needs to be spelled
> > out very clearly.
> > R version 4.2.2 Patched (2022-11-10 r83330) -- "Innocent and Trusting"
> >  > c(-8,8) %/% 3
> > [1] -3  2
> > so we deduce that R *neither* rounds *not* truncates,
> > but returns the floor of the quotient.
> > It is widely argued that flooring division is more
> > generally useful than rounding or truncating division,
> > but it is admittedly surprising.
> >
> > On Tue, 20 Dec 2022 at 02:51, Göran Broström <gb using ehar.se
> > <mailto:gb using ehar.se>> wrote:
> >
> >     I have a long vector x with five-digit codes where the first digit of
> >     each is of special interest, so I extracted them through
> >
> >       > y <- x %/% 10000
> >
> >     but to my surprise y contained the value -1 in some places. It turned
> >     out that x contains -1 as a symbol for 'missing value' so in effect I
> >     found that
> >
> >       > -1 %/% 10000 == -1
> >
> >     Had to check the help page for "%/%", and the first relevant comment
> I
> >     found was:
> >
> >     "Users are sometimes surprised by the value returned".
> >
> >     No surprise there. Further down:
> >
> >     ‘%%’ indicates ‘x mod y’ (“x modulo y”) and ‘%/%’ indicates
> >            integer division.  It is guaranteed that
> >
> >            ‘ x == (x %% y) + y * (x %/% y) ’ (up to rounding error)
> >
> >     I did expect  (a %/% b) to return round(a / b), like gfortran and
> gcc,
> >     but instead I get floor(a / b) in R. What is the reason for these
> >     different definitions? And shouldn't R's definition be documented?
> >
> >     Thanks, Göran
> >
> >     ______________________________________________
> >     R-help using r-project.org <mailto:R-help using r-project.org> mailing list --
> >     To UNSUBSCRIBE and more, see
> >     https://stat.ethz.ch/mailman/listinfo/r-help
> >     <https://stat.ethz.ch/mailman/listinfo/r-help>