blob: b26536d3c7dff3e2f42c173900a9fc9fa3bff29a [file] [log] [blame]
#include "pdefs.h"
#include "precision.h"
#ifdef ASM_16BIT
#include "asm16bit.h"
#endif
/*
* Single-digit remainder
*/
int pimod(u, v)
register precision u;
int v;
{
#ifndef ASM_16BIT
register digitPtr uPtr;
register accumulator temp; /* 0 <= temp < base^2 */
#endif
register digit r = 0, d; /* 0 <= r,d < base */
register int res = 0;
(void) pparm(u);
if (v < 0) d = (digit) -v; else d = (digit) v;
if (d >= BASE) {
errorp(PDOMAIN, "pimod", "divisor too big for single digit");
goto done;
}
if (d == 0) {
errorp(PDOMAIN, "pimod", "divide by zero");
goto done;
}
#ifndef ASM_16BIT
uPtr = u->value + u->size;
r = 0; /* r is current remainder */
do {
temp = mulBase(r); /* 0 <= temp <= (base-1)^2 */
temp += *--uPtr; /* 0 <= temp <= base(base-1) */
r = temp % d; /* 0 <= r < base */
} while (uPtr > u->value);
#else
r = memmodw1(u->value, u->size, d);
#endif
res = (int) r;
if (u->sign) res = -res;
done:
pdestroy(u);
return res;
}