Re: Arbitrary precision modulo operation

Поиск
Список
Период
Сортировка
От Dann Corbit
Тема Re: Arbitrary precision modulo operation
Дата
Msg-id D90A5A6C612A39408103E6ECDD77B829408D6D@voyager.corporate.connx.com
обсуждение исходный текст
Ответ на Arbitrary precision modulo operation  (Chadwick Boggs <chadwickboggs@yahoo.com>)
Ответы Re: Arbitrary precision modulo operation  (Bruno Wolff III <bruno@wolff.to>)
Re: Arbitrary precision modulo operation  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-general

> -----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).

В списке pgsql-general по дате отправления:

Предыдущее
От: Mike Nolan
Дата:
Сообщение: Re: Postgre and Web Request
Следующее
От: "Dann Corbit"
Дата:
Сообщение: Re: Arbitrary precision modulo operation