  lua-l archive

• Subject: Re: Modulo operator produces incorrect results with negative operand(s).
• From: Martin <eden_martin_fuhrspam@...>
• Date: Thu, 9 Feb 2017 03:18:40 -0800

```On 02/08/2017 02:40 PM, chris beck wrote:
>> Hmmm... So why does my programmers calculator, Go, JavaScript, etc,
> etc all return -3 in this case?
>>
>> Personally I think it's a bug, as "2" is not the correct result for
> that expression (in any language but Lua it seems).
>
> For what it's worth, among anyone who was a math major or took a course
> in algebra in college, the congruence class of -2 mod 5 is 3
[snip]

It depends on additional restrictions of mod() results.

Gerenally

mod(n, m) is some function like
: get x, y such that
:   x * m + y == n,
:   int(x), int(y), abs(y) < abs(m)
: return y

And further restrictions possible:
: x = min(possible x) // x leftmost from zero
=> mod(-2, -5):  0 * -5 + -2 => -2         (1)
=> mod( 2, -5): -1 * -5 + -3 => -3
=> mod(-2,  5): -1 *  5 +  3 =>  3
=> mod( 2,  5):  0 *  5 +  2 =>  2

: x = max(possible x) // x rightmost from zero
=> mod(-2, -5):  1 * -5 +  3 =>  3         (2)
=> mod( 2, -5):  0 * -5 +  2 =>  2
=> mod(-2,  5):  0 *  5 + -2 => -2
=> mod( 2,  5):  1 *  5 + -3 => -3

: y = min(possible y) // y leftmost from zero
=> mod(-2, -5):  0 * -5 + -2 => -2         (3)
=> mod( 2, -5): -1 * -5 + -3 => -3
=> mod(-2,  5):  0 *  5 + -2 => -2
=> mod( 2,  5):  1 *  5 + -3 => -3

: y = max(possible y) // y rightmost from zero
=> mod(-2, -5):  1 * -5 +  3 =>  3         (4)
=> mod( 2, -5):  0 * -5 +  2 =>  2
=> mod(-2,  5): -1 *  5 +  3 =>  3
=> mod( 2,  5):  0 *  5 +  2 =>  2

And even more:
: x = min(abs(possible x)) // x towards zero
=> mod(-2, -5):  0 * -5 + -2 => -2         (5)
=> mod( 2, -5):  0 * -5 +  2 =>  2
=> mod(-2,  5):  0 *  5 + -2 => -2
=> mod( 2,  5):  0 *  5 +  2 =>  2

: x = max(abs(possible x)) // x away zero
=> mod(-2, -5):  1 * -5 +  3 =>  3         (6)
=> mod( 2, -5): -1 * -5 + -3 => -3
=> mod(-2,  5): -1 *  5 +  3 =>  3
=> mod( 2,  5):  1 *  5 + -3 => -3

: y = min(abs(possible y)) // y towards zero
=> mod(-2, -5):  0 * -5 + -2 => -2         (7)
=> mod( 2, -5):  0 * -5 +  2 =>  2
=> mod(-2,  5):  0 *  5 + -2 => -2
=> mod( 2,  5):  0 *  5 +  2 =>  2

: y = max(abs(possible y)) // y away zero
=> mod(-2, -5):  1 * -5 +  3 =>  3         (8)
=> mod( 2, -5): -1 * -5 + -3 => -3
=> mod(-2,  5): -1 *  5 +  3 =>  3
=> mod( 2,  5):  1 *  5 + -3 => -3

/*
Due some reason results of (5) and (7) are equal.
Same for results (6) and (8).
*/

So at least six different variants possible. Which one you prefer and why?

-- Martin

```

• Follow-Ups:
• References: