Article View: comp.sys.powerpc
Article #3707Re: WANTED: algorithm to perform 64-bit / 32-bit signed & unsigned divide
From: Robert D. Silverman
Date: Thu, 07 Jul 1994 13:34
Date: Thu, 07 Jul 1994 13:34
111 lines
3835 bytes
3835 bytes
In article <joe.773514139@babel.ho.att.com> 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"
Technical Details
Message-ID:
<2vh094$cn6@linus.mitre.org>Path:
arc1-ca.pugleaf.net!bga.com!news.sprintlink.net!hookup!yeshua.marcam.com!MathWorks.Com!blanket.mitre.org!linus.mitre.org!fatima!bsReferences:
<joe.773514139@babel.ho.att.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 115914,d03dbe620dc4c4b X-Google-Attributes: gid115914,public X-Google-Thread: f8403,d03dbe620dc4c4b X-Google-Attributes: gidf8403,public X-Google-Thread: 1025b4,d03dbe620dc4c4b X-Google-Attributes: gid1025b4,public X-Google-ArrivalTime: 1994-07-07 06:52:27 PST Path: arc1-ca.pugleaf.net!bga.com!news.sprintlink.net!hookup!yeshua.marcam.com!MathWorks.Com!blanket.mitre.org!linus.mitre.org!fatima!bs 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 Lines: 111 Message-ID: <2vh094$cn6@linus.mitre.org> References: <joe.773514139@babel.ho.att.com> NNTP-Posting-Host: fatima.mitre.org Keywords: integer divide