From: bs@fatima.mitre.org (Robert D. Silverman) Newsgroups: comp.sys.powerpc,comp.arch.arithmetic,gnu.misc.discuss Subject: Re: WANTED: algorithm to perform 64-bit / 32-bit signed & unsigned divide Date: 7 Jul 1994 13:34:28 GMT Organization: Research Computer Facility, MITRE Corporation, Bedford, MA NNTP-Posting-Host: fatima.mitre.org Keywords: integer divide In article joe@sanskrit.ho.att.com (Joe Orost) writes: >I'm looking for an algorithm to perform an integer 64-bit / 32-bit >signed divide, and a 64-bit / 32-bit unsigned divide on the PowerPC. >I don't want to use the "DIV" instruction, which is not part of the #define IBASE 1073741824 #define BASE (double)1073741824.0 /************************************************************************/ /* */ /* Low level primitives for 64 bit arithmetic; portable version */ /* */ /************************************************************************/ /************************************************************************/ /* */ /* mod_mul(a,b,c); returns a * b mod c; a,b,c, unsigned 32 bit */ /* integers */ /* */ /************************************************************************/ mod_mult(a,b,c) unsigned long a,b,c; { register unsigned long quo,rem; quo = (unsigned long)((double)a * (double)b/(double) c + .5); rem = a*b - quo*c; if ((long)rem <= -1) rem += c; return(rem); } /************************************************************************/ /* */ /* compute (a * b + c) / 2^30 and (a * b + c) % 2^30 */ /* */ /************************************************************************/ muladd(a,b,c,d) unsigned long a,b,c,d[2]; { register unsigned long rem,quo; register double temp; temp = (double)a * (double)b + (double)c; quo = (unsigned long) (temp/BASE + .5); rem = a*b + c - quo*IBASE; if ((long)rem <= -1) { rem += IBASE; quo--; } d[0] = rem; d[1] = quo; } /************************************************************************/ /* */ /* compute (a * b ) / 2^30 and (a * b ) % 2^30 */ /* */ /************************************************************************/ radmul(a,b,d) unsigned long a,b,d[2]; { register unsigned long rem,quo; register double temp; temp = (double)a * (double)b; quo = (unsigned long) (temp/BASE + .5); rem = a*b - quo*IBASE; if ((long)rem <= -1) { rem += IBASE; quo--; } d[0] = rem; d[1] = quo; } /************************************************************************/ /* */ /* compute (a*2^30 + b)/c and (a*2^30 + b) % c */ /* */ /************************************************************************/ divrem(a,b,c,d) unsigned long a,b,c,d[2]; { register unsigned long rem,quo; register double temp; temp = (double)a * BASE + (double)b; quo = (unsigned long) (temp/(double) c + .5); rem = a*IBASE + b - quo*c; if ((long)rem <= -1) { rem += c; quo--; } d[0] = quo; d[1] = rem; } -- Bob Silverman These are my opinions and not MITRE's. Mitre Corporation, Bedford, MA 01730 "You can lead a horse's ass to knowledge, but you can't make him think"