2

I don't have much knowledge in RPGLE. I am trying to solve this small exercise given to me. I never worked or seen exercises using decimals. I want to get percentage of 7 values. So, I want to do the following calculation.

For example in RPGLE.

DTotal            S              3P 0       
DPercnt           S              2P 2       
 /Free
   Total = 589;
   Percnt = (Total/700)100;
   Dsply Percnt;
   *Inlr = *On;
 /End-Free

Expected output is 84.142857143 or round off decimal places to two (84.14) or four (84.1430) places.

  1. Which Data type I should use for Total and Percent Variables?
  2. How can I declare Percent variable (Packed or Zoned) to hold two or four or N decimal places?
  3. Can anyone please type the declaration part and the calculation part in "RPG IV" or in Fixed-format please?

Errors I got and corrections I carried-out:

  1. The end of the expression is expected. (with in SEU)

    For the above error, I added * and it solved Percnt = (Total/700) * 100;

  2. Below is the second error.

    The target for a numeric operation is too small to hold the result (C G D F)
    

    For above error, I increased Percnt variable length to 4P 2.

  3. But this time answer was wrong, DSPLY 8414. Not as expected.

    So, I used Eval as suggested below. Eval(H) Percnt = (Total/700) * 100;

  4. Still same output: DSPLY 8414.

    Thanks @Barbara. I noticed this tip late. DSPLY (%CHAR(Percnt)) gave me the desired output 84.14.

1 Answers1

5

RPG numeric variables are defined by the total number of digits and number of decimal places. So if you want two integer places and two decimal places (12.34), define the variable as packed(4:2) in free-form or 4P 2 in fixed form.

If you want rounding, code the (H) extender ('H' stands for "half-adjust") for the opcode. The opcode for assignments is the EVAL opcode, which is usually omitted. But you have to code it if you want to add an extender.

DTotal            S              3P 0       
DPercnt           S              4P 2       
   Total = 589;
   Eval(H) Percnt = (Total/700) * 100;
   DSPLY (%CHAR(Percnt));
   *Inlr = *On;

Unless you are on a release prior to 7.1, you don't need to code /FREE and /END-FREE any more.

Barbara Morris
  • 3,195
  • 8
  • 10
  • 1
    By the way, using DSPLY for numeric values doesn't show the decimal point if you just code the variable name. Code DSPLY (%CHAR(Percnt)) to get nicer output with a decimal point. – Barbara Morris Apr 30 '22 at 21:11
  • 1. Thanks for the fast reply. I am using pub400.com for practice. So, I don't know if it is 7.1 or not. 2. So, I should always think in total digits (including decimals) and then mention how many decimal i want as decimals? Am I right? 3. One more question. Is there any other way of rounding without using Eval Opcode? 4. Thank you `DSPLY (%CHAR(Percnt))` Worked. – user3025253 May 02 '22 at 11:25
  • If I need to display `Percnt` I should use `4 2` in display file too? – user3025253 May 02 '22 at 12:14
  • 1
    To round without using the EVAL opcode, you could use the %DECH built-in function. The 'H' in %DECH indicates that it returns a rounded result. Percnt = %DECH((Total/700) * 100 : 4 : 2); But to use %DECH to round to 2 decimal places, you have to specify the length and decimals operands of %DECH. To me, coding EVAL(H) "looks" better. To me, using %DECH would make it more difficult to "see" the calculation for the percentage. – Barbara Morris May 04 '22 at 11:46
  • 1
    About the display file, yes, the numeric definition in the display file would also be in the total-length and decimal-places form, 4 2. – Barbara Morris May 04 '22 at 11:47
  • 1
    This site https://pub400.com/ says that it is at the 7.4 release. – Barbara Morris May 04 '22 at 11:50