George Woltman wrote:

>The bug was in the routine mulmod which was supposed to compute a * b 
mod c
>The implementation was a rather sloppy:
>        unsigned long tmp;
>        tmp = a * (b & 0x3FF);
>        tmp += ((a << 10) % c) * (b >> 10);
>        return (tmp % c);
>You can see in the first computation of tmp there will be an overflow 
if
>a exceeds 2^22 or 4194304.  The new implementation is:
>        double  tmp;
>        unsigned long q;
>        tmp = (double) a * (double) b;
>        q = (unsigned long) (tmp / (double) c);
>        return ((unsigned long) (tmp - (double) q * (double) c));
>This implementation isn't perfect, but will work as long as a * b does
>not exceed 53 bits.

This got me thinking, since I've had a use for modular multiplication in 
some of the little programs that I've bee writing. Based on your code, I 
wrote the following:

unsigned long mulmod(unsigned long a, unsigned long b, unsigned long n)
{
        long double tmp, q;
        tmp = a * (long double)b;
        q = floorl(a * (long double)b / n);
        return tmp - q * n;
}

In my testing, this appears to give the correct result for any 32-bit 
values of a, b, and n, thanks to the 64-bit precision of Intel's 80-bit 
floating point type. Is there anything wrong with this approach? It 
depends on having a long double version of the floor function, which is 
available on my Borland compiler.
Get Your Private, Free Email at http://www.hotmail.com
________________________________________________________________
Unsubscribe & list info -- http://www.scruz.net/~luke/signup.htm

Reply via email to