Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll) git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
150 lines
2.6 KiB
C
Executable File
150 lines
2.6 KiB
C
Executable File
/* int _DivProcFast(c,a,b);
|
|
*
|
|
* ARGUMENT
|
|
* DEC *c;
|
|
* DEC *a,b;
|
|
*
|
|
* DESCRIPTION
|
|
* This routine divides one positive DEC structure by another, setting
|
|
* dst = src1 / src2.
|
|
*
|
|
* SIDE EFFECTS
|
|
* None.
|
|
*
|
|
* RETURNS
|
|
* None.
|
|
*
|
|
* ALGORITHM
|
|
* a = an * 10^-ad
|
|
* b = bn * 10^-bd
|
|
* c = a / b
|
|
* c = (10^p * an / bn) * 10^[-(ad - bd + p)]
|
|
* cn = 10^p * an / bn, cd = ad - bd + p
|
|
*
|
|
* AUTHOR
|
|
* Jared Levy 05-JAN-1987 17:30
|
|
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
|
|
*
|
|
* MODIFICATIONS
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "gm.h"
|
|
#include "gmsystem.h"
|
|
|
|
int _DivProcFast(c,a,b)
|
|
DEC *c;
|
|
DEC *a,*b;
|
|
{
|
|
register int i,t;
|
|
int maxp, p=0, mag2a, mag2b;
|
|
unsigned SHORT an[14], bn[6], *cn, ad[5], as[14];
|
|
|
|
/* sets c = a / b,
|
|
where a and b are positive DEC numbers, and the result is stored in c */
|
|
|
|
bn[0]=b->dc.sl[0];
|
|
bn[1]=b->dc.sl[1];
|
|
bn[2]=b->dc.sl[2];
|
|
bn[3]=b->dc.sl[3];
|
|
bn[4]=b->dc.msd;
|
|
bn[5]=0;
|
|
|
|
cn = c->dc.sl;
|
|
|
|
an[0]=a->dc.sl[0];
|
|
an[1]=a->dc.sl[1];
|
|
an[2]=a->dc.sl[2];
|
|
an[3]=a->dc.sl[3];
|
|
an[4]=a->dc.msd;
|
|
an[5] = 0;
|
|
an[6] = 0;
|
|
an[7] = 0;
|
|
an[8] = 0;
|
|
an[9] = 0;
|
|
an[10]= 0;
|
|
an[11]= 0;
|
|
|
|
maxp = GM_MAXID - (a->dc.id - b->dc.id);
|
|
if (maxp > 0) {
|
|
|
|
/* The following code uses up most of the time involved in divisions.
|
|
It starts with two 64-bit number integers an and bh, both positive,
|
|
along with an integer maxp. Two values are returned: a nonnegative
|
|
integer p and a 160-bit number as = an * 10^p. p is the largest number
|
|
satisfying the conditions (1) as < 2^160,
|
|
(2) the highest 80 bits of as are less than bh
|
|
(3) p <= maxp.
|
|
*/
|
|
|
|
i = 4;
|
|
while (an[i] == 0)
|
|
i--;
|
|
mag2a = 16 * i;
|
|
t = an[i]>>1;
|
|
while (t) {
|
|
t=t>>1;
|
|
mag2a++;
|
|
}
|
|
|
|
i = 4;
|
|
while ((bn[i] == 0) && (i>0))
|
|
i--;
|
|
mag2b = 16 * i;
|
|
t = bn[i]>>1;
|
|
while (t) {
|
|
t=t>>1;
|
|
mag2b++;
|
|
}
|
|
|
|
p = (78 - 16 + mag2b - mag2a) * 3 / 10;
|
|
if (p>maxp)
|
|
p=maxp;
|
|
|
|
|
|
if (p != 0)
|
|
_MulUnsArrByPwrOf10(an,p,10);
|
|
|
|
if (p != maxp) {
|
|
|
|
for(i=0; i<14; i++) {
|
|
as[i] = an[i];
|
|
}
|
|
|
|
i = _MulUnsArrByPwrOf10(as,1,10);
|
|
|
|
ad[0]=as[4];
|
|
ad[1]=as[5];
|
|
ad[2]=as[6];
|
|
ad[3]=as[7];
|
|
ad[4]=as[8];
|
|
_DoubleUnsArr(ad, 5);
|
|
if (as[4]&0x8000)
|
|
ad[0]=ad[0]+1;
|
|
|
|
if ((i == GM_SUCCESS) &&
|
|
(_CompareUnsArr(ad,bn,5) == -1)) {
|
|
p++;
|
|
for(i=0; i<10; i++)
|
|
an[i] = as[i];
|
|
}
|
|
}
|
|
/* p != maxp */
|
|
|
|
} /* maxp > 0 */
|
|
|
|
_DivUns10ArrByUns5Arr(cn,an,bn);
|
|
|
|
/* adjust implied decimal to correct value */
|
|
i = a->dc.id - b->dc.id + p;
|
|
if (i<GM_MINID)
|
|
return(GM_OVERFLOW);
|
|
if (i>GM_MAXID) {
|
|
_DivUnsArrByPwrOf10(cn, 5, i-GM_MAXID);
|
|
i = GM_MAXID;
|
|
}
|
|
c->dc.id = i;
|
|
return(GM_SUCCESS);
|
|
}
|