> -----Original Message-----
> From: Bruno Wolff III [mailto:bruno@wolff.to]
> Sent: Wednesday, April 28, 2004 12:05 AM
> To: Tom Lane
> Cc: Paul Tillotson; pgsql-general@postgresql.org
> Subject: Re: [GENERAL] Arbitrary precision modulo operation
>
>
> On Wed, Apr 28, 2004 at 02:01:00 -0400,
> Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Paul Tillotson <pntil@shentel.net> writes:
> > > mod(x, y) is computed as x - trunc(x / y) * y in the mod_var()
> > > function
> >
> > It could be that select_div_scale needs to allow some more slop, or
> > that that routine is okay but mod_var shouldn't depend on
> it to select
> > the intermediate result scale for its internal division. Comments?
>
> One option would be to define a separate division operator
> that always returns an integral value and that is truncated
> toward 0 and use that for the mod function. People might find
> this operator useful in itself.
It will give some wrong results. The result of mod should be the
remainder after division, which is not always integral in the case of
numeric fixed point or floating point.
Consider the output of this program:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
int main(void)
{
int i;
double den,
other;
srand((unsigned) time(NULL));
for (i = 0; i < 10; i++) {
den = rand() + 1.0;
other = 1.0 + rand() / (rand() + 1.0);
printf("%f mod %f is %f\n", other, den, fmod(other, den));
printf("%f mod %f is %f\n", den, other, fmod(den, other));
}
return 0;
}
> Another option would be for mod to check if the remainder
> doesn't have the same sign as the divisor and if so keeping
> adding the divisor to it until it does.
I would suggest computation in sufficient digits of accuracy to get a
correct answer. If any precision is lost in numeric calculations then
an error of PLOSS should be returned (unless somehow there is a total
loss of precision).