Round Decimal

From MidrangeWiki
Revision as of 16:14, 17 December 2018 by DaveLClarkI (talk | contribs) (Summary)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Summary

The following are the RPG/LE fully free-form definitions and instructions needed for using the Round Decimal service procedure. This service procedure simply allows the caller to round a decimal number to a specified number of decimals. Optionally, custom rounding is also available—such as always rounding down or always rounding up.

By Dave Clark

Service Prototype

Place the following in a separate copybook for inclusion in both the caller and the service program source members.

**free

//==============================================================================
// This procedure rounds the passed number to the specified number of decimal
// positions as the returned result.  Maximum result decimals is nine and that
// is also the default.  For normal rounding (where .4 or below rounds down
// while .5 or above rounds up) do not pass the third parm.  Optionally, pass
// the maximum decimal value to round down.  Examples:
// .9 always rounds down, .0 always rounds up, and .4 is normal rounding.
//==============================================================================
dcl-pr GenUtl_roundDecimal   packed(31:9);
  pNumber                    packed(33:11)  const;
  pDecimals                  uns(3)         const  options(*nopass:*omit);
  pRoundAt                   packed(1:1)    const  options(*nopass);
end-pr;

Service Procedure

Place the following in a service program source member.

**free
ctl-opt NoMain AlwNull(*UsrCtl) Debug Option(*SrcStmt:*NoDebugIo)
        DatFmt(*ISO) TimFmt(*ISO);

//==============================================================================
// This procedure rounds the passed number to the specified number of decimal
// positions as the returned result.  Maximum result decimals is nine and that
// is also the default.  For normal rounding (where .4 or below rounds down
// while .5 or above rounds up) do not pass the third parm.  Optionally, pass
// the maximum decimal value to round down.  Examples:
// .9 always rounds down, .0 always rounds up, and .4 is normal rounding.
//==============================================================================
dcl-proc GenUtl_roundDecimal export;
  dcl-pi *n                  packed(31:9);
    pNumber                  packed(33:11)  const;
    pDecimals                uns(3)         const  options(*nopass:*omit);
    pRoundAt                 packed(1:1)    const  options(*nopass);
  end-pi;

  dcl-s adjustBy             int(10:0);
  dcl-s iRoundBy             packed(1:1)    inz(.5);

  if %parms() < %parmnum(pDecimals)    // if parm not passed
  or %addr(pDecimals) = *null          // or it was omitted
  or pDecimals > 9;                    // or is greater than internal limit
    adjustBy = 10 ** 9;                // default adjust by internal limit
  else;                                // else
    adjustBy = 10 ** pDecimals;        // adjust by decimal positions specified
  endif;

  if %parms() < %parmnum(pRoundAt)     // if parm not passed
  or %addr(pRoundAt) = *null;          // or it was omitted
  else;                                // use default rounding, else
    iRoundBy = .9 - %abs(pRoundAt);    // calculate the rounding factor
  endif;

  return (%int(pNumber * adjustBy + iRoundBy) / adjustBy); // return rounded val
end-proc;