• Subject: Re: Bug modulo operator on negative numbers
• Date: Mon, 16 Aug 2021 17:38:13 +0200

There are several variants of modulo operations,[1] and the documentation isn't very clear on which variant is used by Lua. It is quite easy to get strange results when using algorithms that depend on modulo operations. Perhaps the doc should say something about the different versions.

On Mon, Aug 16, 2021 at 11:51 AM Francisco Olarte <folarte@peoplecall.com> wrote:
On Mon, Aug 16, 2021 at 9:33 AM Domingo Alvarez Duarte
>
> There was some discussion about Lua modulo operator with negative
> numbers but it doesn't seem to be addressed properly yet, see the
> examples bellow.

> local a2 = -4;
> local b2 = 3;
> local c2 = a2 % b2;
> local d2 = a2 - c2;
> print( a, b, c, d, a2, b2, c2, d2);
> 4    3    1    3    -4    3    2    -6

What is the problem? It is doing it per the manual.
"Floor division (//) is a division that rounds the quotient towards
minus infinity, resulting in the floor of the division of its
operands.
Modulo is defined as the remainder of a division that rounds the
quotient towards minus infinity (floor division). "

Adding the floor division to the chek:
> a=-4
> b=3
> c = a % b
> d = a - c
> ee = a//b
> ff = b * ee + c
> gg = a - ( b * ee )
> print (a,b,c,d,ee,ff,gg)
-4    3    2    -6    -2    -4    2

gg is remainder  as numerator minus denominator times quotient, the
same as c. Doing it in fractions e will be -1-1/3, -2 rounded to minus
inifinity.

C does it in another way. I have not got a C standard at hand, but may
go-top web, cpp reference.com states:

"Division

The binary operator / divides the first operand by the second (after
usual arithmetic conversions) following the usual arithmetics
definitions, except that

when the type after usual arithmetic conversions is an integer type,
the result is the algebraic quotient (not a fraction), rounded in
implementation-defined direction (until C99)truncated towards zero
(since C99)
....

Remainder

The binary operator % yields the remainder of the division of the
first operand by the second (after usual arithmetic conversions).

The sign of the remainder is defined in such a way that if the
quotient a/b is representable in the result type, then (a/b)*b + a%b
== a.
"
So, % in lua is not the same as in C by definition, results are expected.

Francisco Olarte.