Reported by me in https://github.com/davidgiven/ack/issues/60
This doesn't change DIV. Right now a DIV b does floor division and
a MOD b has the sign of b. This is the same as Lua, Python, Ruby,
Tcl; but is different from other Modula-2 implementations.
break;
case DIV:
- case MOD:
if (o2 == 0) {
- node_error(exp, exp->nd_symb == DIV ?
- "division by 0" :
- "modulo by 0");
+ node_error(exp, "division by 0");
return;
}
if ((o1 < 0) != (o2 < 0)) {
if (o1 < 0) o1 = -o1;
else o2 = -o2;
- if (exp->nd_symb == DIV) o1 = -((o1+o2-1)/o2);
- else o1 = ((o1+o2-1)/o2) * o2 - o1;
+ o1 = -((o1+o2-1)/o2);
}
- else {
- if (exp->nd_symb == DIV) o1 /= o2;
- else o1 %= o2;
+ else o1 /= o2;
+ break;
+
+ case MOD:
+ if (o2 == 0) {
+ node_error(exp, "modulo by 0");
+ return;
+ }
+ {
+ arith m = o1 % o2;
+ if (m != 0 && (o1 < 0) != (o2 < 0))
+ o1 = m + o2;
+ else
+ o1 = m;
}
break;
rmi(j,i)
int j,i;
{
+ int m;
+
if (j == 0) TRP(EIDIVZ);
if (i == 0) return 0;
- if ((i < 0) != (j < 0)) {
- if (i < 0) i = -i;
- else j = -j;
- return j*((i+j-1)/j)-i;
- }
- else return i%j;
+
+ m = i % j;
+ if (m != 0 && (i < 0) != (j < 0))
+ m += j;
+ return m;
}
long
rmil(j,i)
long j,i;
{
+ long m;
+
if (j == 0) TRP(EIDIVZ);
if (i == 0) return 0L;
- if ((i < 0) != (j < 0)) {
- if (i < 0) i = -i;
- else j = -j;
- return j*((i+j-1)/j)-i;
- }
- else return i%j;
+
+ m = i % j;
+ if (m != 0 && (i < 0) != (j < 0))
+ m += j;
+ return m;
}