/* int _AddDec80Bit(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 * Adds 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 GM_IMINID, * the minimum allowed implied decimal. * * SIDE EFFECTS * On overflow, the *pDst value is indeterminate. * * RETURNS * Returns GM_SUCCESS if no error, else failure code. * * Note: uses an assembly language routine for the actual math * * AUTHOR * Jared Levy * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * */ #include #include "gm.h" #include "gmsystem.h" int _AddDec80Bit(pDst,pSrc1,pSrc2) DEC *pDst; DEC *pSrc1,*pSrc2; { DEC t1, t2, *pts; register int i, j; int s1, s2; i = pSrc1->dc.id-pSrc2->dc.id; if (i) { pts = &t1; _MacDCopy(pts, pSrc1); pts = &t2; _MacDCopy(pts, pSrc2); if (i<0) { pSrc1 = &t1; pSrc2 = &t2; i = -i; } else { pSrc2 = &t1; pSrc1 = &t2; } j = _MulUnsArrByPwrOf10Limited(pSrc1->dc.sl, i, 5); pSrc1->dc.id += j; if (jdc.sl, 5, i-j); } /* add the numbers */ pDst->dc.id = pSrc1->dc.id; s1 = pSrc1->dc.attr & 0x0001; s2 = pSrc2->dc.attr & 0x0001; 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[4] >= 32768L) { if (pSrc1->dc.id <= GM_IMINID) return(GM_OVERFLOW); _DivUnsArrByUns(pDst->dc.sl, 10, 5); 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; } } return(GM_SUCCESS); }