Tuesday 20 January 2015

Modulo operations

Introduction

Modulo operations in different languages are not always the same because there are several different definitions of modulo: truncated division, floored division and Euclidean definition (from modulo operation in WiKi).
Assume a stands for the dividend, b for the divisor, q for the quoitant and r for the remainder. And provide “/“ is a float division.

truncated division

truncation towards zero (truncated division): the remainder as the same sign as the dividend
q = trunc(a/b)
r = a - b*q
therefore,
  • if a = 3, b = 2, then q = 1, r = 1
  • if a = -3, b = 2, then q = -1, r = -1
  • if a = 3, b = -2, then q = -1, r = 1
  • if a = -3, b = -2, then q = 1, r = -1
    In sum, “a = b*trunc(a/b) + a mod b”

floored division

truncation towards minus infinity (floored division): the remainder has the same sign as the divisor.
q = floor(a/b)
r = a - b*q
therefore,
  • if a = 3, b = 2, then q = 1, r = 1
  • if a = -3, b = 2, then q = -2, r = 1
  • if a = 3, b = -2, then q = -2, r = -1
  • if a = -3, b = -2, then q = 1, r = -1
    In sum, “a = b*floor(a/b) + a mod b”

Euclidean definition

Euclidean definition: the remainder is always positive or 0
q = floor(a/b) if b > 0
q = ceil(a/b) if b < 0
r = a - b*q
therefore,
  • if a = 3, b = 2, then q = 1, r = 1
  • if a = -3, b = 2, then q = -2, r = 1
  • if a = 3, b = -2, then q = -1, r = 1
  • if a = -3, b = -2, then q = 2, r = 1

modulo in Z and SICStus Prolog

  • modulo in Z uses truncation towards minus infinity (from “The Z Notation: A Reference Manual”)
  • modulo in Prolog: the integer remainder after floored division of X by Y (from SICStus Prolog user manual)