hoc: fix %= operator for large values

Operator %= calculated different values than ordinary
modulus operator:

  a=1e20
  a % 47
  18
  a %= 47
  print a
  -36

Also add division-by-zero check to /= and %= operators.

Signed-off-by: Juha Niskanen <juniskane@gmail.com>
This commit is contained in:
Juha Niskanen 2024-05-16 17:49:57 +03:00
parent ace7bcb75b
commit 2911bbb8a3

View file

@ -557,6 +557,8 @@ diveq(void)
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
execerror("assignment to non-variable",
d1.sym->name);
if (d2.val == 0.0)
execerror("division by zero", (char *)0);
d2.val = d1.sym->u.val /= d2.val;
d1.sym->type = VAR;
push(d2);
@ -572,18 +574,16 @@ void
modeq(void)
{
Datum d1, d2;
long x;
d1 = pop();
d2 = pop();
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
execerror("assignment to non-variable",
d1.sym->name);
if (d2.val == 0.0)
execerror("division by zero", (char *)0);
/* d2.val = d1.sym->u.val %= d2.val; */
x = d1.sym->u.val;
x %= (long) d2.val;
d2.val = x;
d1.sym->u.val = x;
d2.val = d1.sym->u.val = fmod(d1.sym->u.val, d2.val);
d1.sym->type = VAR;
/* push(d2) generates a compiler error on Linux w. gcc 2.95.4 */