campo-sirio/gfm/roundcnt.c

97 lines
1.9 KiB
C
Raw Normal View History

/* 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 <stdio.h>
#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);
}