lua-users home
lua-l archive

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


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.

Example:

====

local a = 4;
local b = 3;
local c = a % b;
local d = a - c;


local a2 = -4;
local b2 = 3;
local c2 = a2 % b2;
local d2 = a2 - c2;

print( a, b, c, d, a2, b2, c2, d2);

====

Output:

====

4    3    1    3    -4    3    2    -6

====

Code on lua.vm (note the comments):

====

/*
** Integer modulus; return 'm % n'. (Assume that C '%' with
** negative operands follows C99 behavior. See previous comment
** about luaV_idiv.)
*/
lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) {
  if (l_unlikely(l_castS2U(n) + 1u <= 1u)) {  /* special cases: -1 or 0 */
    if (n == 0)
      luaG_runerror(L, "attempt to perform 'n%%0'");
    return 0;   /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
  }
  else {
    lua_Integer r = m % n;
    if (r != 0 && (r ^ n) < 0)  /* 'm/n' would be non-integer negative? */
      r += n;  /* correct result for different rounding */
    return r;
  }
}

====

C example:

====

#include <stdio.h>

int main(int argc, char *argv[]) {

    int a = 4;
    int b = 3;
    int c = a % b;
    int d = a - c;


    int a2 = -4;
    int b2 = 3;
    int c2 = a2 % b2;
    int d2 = a2 - c2;

    printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", a, b, c, d, a2, b2, c2, d2);

    return 0;
}

====

C output:

====

4    3    1    3    -4    3    -1    -3

====

Cheers !