/* DEC *RoundCents(pDst,pSrc1,cents) * * ARGUMENT * pDst is a pointer to the destination DEC structure. * pSrc1 is a ptr to the source1 DEC structure. * cents is the int number of cents to round to * * DESCRIPTION * Rounds pSrc1 to the nearest cents pennies, storing result in pDst. * For example, if cents == 5, rounds to the nearest nickle. * The result always has two decimal places. * * SIDE EFFECTS * pSrc1 remains unchanged and pDst is undefined on error. * * RETURNS * Returns a pointer to the pDst structure unless error, * in which case it returns a NULL(a C false). On error, the error * is in wGMError, unless an error was already there. * * POSSIBLE ERROR CODES * * GM_NULLPOINTER * GM_ARGVAL * GM_OVERFLOW * GM_UNDERFLOW * * AUTHOR * Jared Levy 10/1/89 * Copyright (C) 1989-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * */ #include #include "gm.h" #include "gmsystem.h" DEC *RoundCents(pDst,pSrc1,cents) DEC *pDst, *pSrc1; int cents; { register int r; unsigned long i; DEC *p, dtmp, *tmp=&dtmp; _MacStart(GM_ROUNDCNT); if (cents<=0) { _MacErr(GM_ARGVAL); _MacRet(GM_NULL); } _MacOutVarD(pDst); /* round to two decimals */ if (cents % 2) p = RoundDecimal(tmp, pSrc1, 2); else p = TruncateDecimal(tmp, pSrc1, 2); if (!p) { _MacRet(GM_NULL); } _MacDCopy(pDst, tmp); if (_MacIsDecZ(tmp)) { _MacRet(pDst); } /* determine remainder of division */ r = _DivUnsArrByUns(tmp->dc.sl, cents, 5); if (r==0) { _MacRet(pDst); } /* round up or down to nearest multiple */ if ((unsigned) (2*r) >= (unsigned) cents) { /* round up */ i = (unsigned long) (cents - r); pDst->ls.lsl[0] += i; if (pDst->ls.lsl[0] < i) pDst->ls.lsl[1]++; } else { /* round down */ i = (unsigned long) r; if (pDst->ls.lsl[0] < i) pDst->ls.lsl[1] --; pDst->ls.lsl[0] -= i; if (_MacIsDecZ(pDst)) _MacErr(GM_UNDERFLOW); } _MacRet(pDst); }