#!/usr/bin/ruby
#
## Tests for the modulo operator
#
var m = 5;
var x = (100! + m);
var y = 23;
assert_eq( x % y, m);
assert_eq(-x % -y, -m);
assert_eq( x % -y, m - y);
assert_eq(-x % y, y - m);
assert_eq( x.rat % y.rat, m);
assert_eq(-x.rat % -y.rat, -m);
assert_eq( x.rat % -y.rat, m - y);
assert_eq(-x.rat % y.rat, y - m);
var f1 = 399.8;
var f2 = 41.2;
assert_eq( f1 % f2 -> roundf( 0), 29);
assert_eq(-f1 % -f2 -> roundf( 0), -29);
assert_eq( f1 % -f2 -> roundf(-1), -12.2);
assert_eq(-f1 % f2 -> roundf(-1), 12.2);
for a,b in [[657512488, -20663738120], [-657512488, -20663738120], [-657512488, 20663738120]] {
assert_eq([divmod(a,b)], [floor(a/b), a%b], [a,b])
}
for n in (31..33, 63..65), k in (31..33, 63..65), m in (31..33, 63..65) {
var a = irand(1 << n)*[1,-1].rand
var b = irand(1 << k)*[1,-1].rand
var c = irand(1 << [k,n].rand)*[1,-1].rand
var M = irand(1 << m)
M || next
assert_eq(imod(a - b, M), (a - b) % M, [a,b,M])
assert_eq(imod(a - b,-M) % -M, (a - b) % -M, [a,b,-M])
assert_eq(addmod(a, b, M), (a+b) % M, [a,b,M])
assert_eq(addmod(a, b,-M) % -M, (a+b) % -M, [a,b,-M])
assert_eq(submod(a, b, M), (a-b) % M, [a,b,M])
assert_eq(submod(a, b,-M) % -M, (a-b) % -M, [a,b,-M])
assert_eq(mulmod(a, b, M), (a*b) % M, [a,b,M])
assert_eq(mulmod(a, b,-M) % -M, (a*b) % -M, [a,b,-M])
assert_eq(addmulmod(a, b, c, M), (a + b*c) % M, [a,b,c,M])
assert_eq(addmulmod(a, b, c,-M) % -M, (a + b*c) % -M, [a,b,c,-M])
assert_eq(submulmod(a, b, c, M), (a - b*c) % M, [a,b,c,M])
assert_eq(submulmod(a, b, c,-M) % -M, (a - b*c) % -M, [a,b,c,-M])
assert_eq(muladdmod(a, b, c, M), (a*b + c) % M, [a,b,c,M])
assert_eq(muladdmod(a, b, c,-M) % -M, (a*b + c) % -M, [a,b,c,M])
assert_eq(mulsubmod(a, b, c, M), (a*b - c) % M, [a,b,c,M])
assert_eq(mulsubmod(a, b, c,-M) % -M, (a*b - c) % -M, [a,b,c,M])
if (b != 0) {
assert_eq([divmod(a,b)], [floor(a/b), a%b], [a,b])
assert_eq([divmod(a,b)], [idiv(a,b), imod(a,b)], [a,b])
}
if (b.is_coprime(M)) {
assert_eq(divmod(a, b, M), (a*invmod(b,M))%M, [a,b,M])
assert_eq(divmod(a, b, -M) % -M, (a*invmod(b,-M)) % -M, [a,b,-M])
}
}
say "** Test passed!";