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);
 | 
						|
}
 |