lua-users home
lua-l archive

Re: Modulo operator produces incorrect results with negative operand(s).

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

AltStyle によって変換されたページ (->オリジナル) /