/* DEC *ModuloDecimal(pDst, pSrc1, pSrc2); * * ARGUMENT * DEC *pDst, *pSrc1, *pSrc2; * * DESCRIPTION * Sets pDst = pSrc1 mod pSrc2. * * SIDE EFFECTS * None. * * RETURNS * pDst if successful, otherwise GM_NULL. * * POSSIBLE ERRORS * GM_NULLPOINTER * GM_DIV0 (if pSrc2 == 0) * * ALGORITHM * a mod b = a - int(a / b) * b * * AUTHOR * Jared Levy * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * * */ #include #include "gm.h" #include "gmsystem.h" DEC *ModuloDecimal(pDst, pSrc1, pSrc2) DEC *pDst, *pSrc1, *pSrc2; { DEC dquot, *quot=&dquot, dprod, *prod=&dprod; int i; _MacStart(GM_DMOD); _MacInVarD(pSrc1); _MacInVarD(pSrc2); _MacOutVarD(pDst); if (_MacIsDecZ(pSrc2)) { _MacErr(GM_DIV0); _MacRet(GM_NULL); } i = _DivTrnDec80Bit(quot, pSrc1, pSrc2, 0); /* overflow here indicates pSrc1 mod pSrc2 = 0 */ if (i == GM_OVERFLOW) { _MacDZero(pDst); pDst->dc.id = pSrc1->dc.id; _MacRet(pDst); } /* overflow not possible here since |prod| <= |pSrc1| */ (void) _MulDec80Bit(prod, quot, pSrc2); (void) _Sq5UnsTo4Uns(prod); /* result must be 64 bits since |prod| <= |pSrc1| */ (void) _SubDec80Bit(pDst, pSrc1, prod); _MacRet(pDst); }