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
		
			
				
	
	
		
			131 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* DEC	*SubtractDecimal(pDst,pSrc1,pSrc2)
 | |
|  *
 | |
|  * ARGUMENT
 | |
|  *	pDst is	a pointer to the destination DEC structure.
 | |
|  *	pSrc1 is a ptr to the source1 DEC structure.
 | |
|  *	pSrc2 is a ptr to the source2 DEC structure.
 | |
|  *
 | |
|  * DESCRIPTION
 | |
|  *	Subtracts the value in pSrc1 DEC to the	value in pSrc2 DEC
 | |
|  *   and puts the result in dest DEC structure.	 The sum is calculated
 | |
|  *   to	the maximum possible accuracy.	The routine requires MINID,
 | |
|  *   the minimum allowed implied decimal.
 | |
|  *
 | |
|  * SIDE	EFFECTS
 | |
|  *	On overflow, the dest value is indeterminate.
 | |
|  *
 | |
|  * RETURNS
 | |
|  *	Returns	a pointer to the dest structure	unless overflow,
 | |
|  *   when it returns a GM_NULL.
 | |
|  *
 | |
|  * POSSIBLE ERROR CODES
 | |
|  *
 | |
|  *	GM_NULLPOINTER
 | |
|  *	GM_OVERFLOW
 | |
|  *
 | |
|  * AUTHOR
 | |
|  *  Jared Levy
 | |
|  *   Copyright (C) 1987-1990 Greenleaf Software	Inc.  All rights reserved.
 | |
|  *
 | |
|  * MODIFICATIONS
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include "gmsystem.h"
 | |
| 
 | |
| DEC	*SubtractDecimal(pDst,pSrc1,pSrc2)
 | |
| DEC	*pDst;
 | |
| DEC	*pSrc1,*pSrc2;
 | |
| {
 | |
| 	DEC	t1, t2,	*pts;
 | |
| 	register int	i,j;
 | |
| 	int	s1, s2;
 | |
| 
 | |
| 	_MacStart(GM_DSUB);
 | |
| 
 | |
| 	_MacInVar(pSrc1,GM_NULL);
 | |
| 	_MacInVar(pSrc2,GM_NULL);
 | |
| 	_MacOutVar(pDst,GM_NULL);
 | |
| 
 | |
| /* if the source id's are different, make them equal with as much accuracy
 | |
|    as is possible, and protect source fields from change */
 | |
| 
 | |
| /* line	up decimal places */
 | |
| 	i = pSrc1->dc.id-pSrc2->dc.id;
 | |
| 	if (i)	{
 | |
| 		pts = &t1;
 | |
| 		_MacDCopy(pts, pSrc1);
 | |
| 		pts = &t2;
 | |
| 		_MacDCopy(pts, pSrc2);
 | |
| 		_MacDChgs(pts);
 | |
| 
 | |
| 		if (i<0)  {
 | |
| 			pSrc1 =	&t1;
 | |
| 			pSrc2 =	&t2;
 | |
| 			i = -i;
 | |
| 		}
 | |
| 		else  {
 | |
| 			pSrc2 =	&t1;
 | |
| 			pSrc1 =	&t2;
 | |
| 		}
 | |
| 
 | |
| 		j = _MulUnsArrByPwrOf10Limited(
 | |
| 			pSrc1->dc.sl, i, 4);
 | |
| 		pSrc1->dc.id +=	j;
 | |
| 		if (j<i)
 | |
| 			_DivUnsArrByPwrOf10(pSrc2->dc.sl, 4, i-j);
 | |
| 	}
 | |
| 
 | |
| 	s1 = pSrc1->dc.attr & 0x0001;
 | |
| 	s2 = pSrc2->dc.attr & 0x0001;
 | |
| 	if (i==0)
 | |
| 		s2=1-s2;
 | |
| 
 | |
| 	/* Subtract the	numbers	*/
 | |
| 	pDst->dc.id = pSrc1->dc.id;
 | |
| 
 | |
| 	if (s1 == s2)  {
 | |
| /* Add absolute	values if signs	are equal */
 | |
| 		_AddUnsArrToUnsArr(pSrc1->dc.sl, pSrc2->dc.sl,
 | |
| 			pDst->dc.sl,5);
 | |
| 
 | |
| /* if the first addition is an overflow, round down and	try again  */
 | |
| 		if (pDst->dc.sl[3] >= 32768L) {
 | |
| 			if (pSrc1->dc.id <= GM_MINID)  {
 | |
| 				_MacErr(GM_OVERFLOW);
 | |
| 				_MacRet(GM_NULL);
 | |
| 			}
 | |
| 			_DivUnsArrByUns(pDst->dc.sl, 10, 4);
 | |
| 			pDst->dc.id--;
 | |
| 		}
 | |
| 
 | |
| 	/* sign	of pDst	same as	sign of	sources	*/
 | |
| 		pDst->dc.attr =	s1;
 | |
| 	}
 | |
| 
 | |
| 	else  {
 | |
| /* subtract larger absolute value from smaller if signs	are different */
 | |
| 		if (_CompareUnsArr(pSrc1->dc.sl,
 | |
| 			 pSrc2->dc.sl, 5) >= 0)	 {
 | |
| 		/* pSrc1 has larger absolute value */
 | |
| 			 (void)	_SubUnsArrFromUnsArr(pSrc1->dc.sl,
 | |
| 				pSrc2->dc.sl,
 | |
| 				pDst->dc.sl,5);
 | |
| 		/* sum has same	sign as	pSrc1 */
 | |
| 			pDst->dc.attr =	s1;
 | |
| 		}
 | |
| 
 | |
| 		else  {
 | |
| 		/* pSrc2 has larger absolute value */
 | |
| 		(void)	_SubUnsArrFromUnsArr(pSrc2->dc.sl,
 | |
| 				pSrc1->dc.sl,
 | |
| 				pDst->dc.sl,5);
 | |
| 		/* sum has same	sign as	pSrc2 */
 | |
| 		pDst->dc.attr =	s2;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	_MacRet(pDst);
 | |
| }
 |