Page 1 of 1

COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 3:53 pm
by nikesh_rai
Hi Guys,

I have a doubt in below given code:

 DATA DIVISION.                             
 WORKING-STORAGE SECTION.                   
 01 A  PIC 99   VALUE 5.                     
 01 B  PIC 9V9  VALUE 6.                     
 01 C  PIC 99V9 VALUE 2.5.                   
 01 D  PIC 99   VALUE 3.                     
 PROCEDURE DIVISION.                         
 A100-SECTION SECTION.                       
     COMPUTE A ROUNDED B C = A+B*C/D.       
D    DISPLAY 'A      : ' A                   
D    DISPLAY 'B      : ' B                   
D    DISPLAY 'C      : ' C                   
     .                                       
     EXIT.                                   
     STOP RUN.


When I compiled the code and ran it, i got the following output:
A      : 10     
B      : 00     
C      : 100     


however, when I used the same code and ran it on online COBOL compiler (available on Internet), I got a different result:

A:10
B:6.0
C:10.0

However, I will trust the results what I got using mainframe, I still want to know how the value of B and C is being calculated here. and I saw somewhere that ROUNDED has no impact on COMPUTE (I don't remember the link). So, is it true.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 4:39 pm
by Akatsukami
  1. The mainframe DISPLAY is of exactly what you've coded; i.e., zoned decimal with assumed but not printed points. The "online" compiler is adding printed decimal points.
  2. The order of precedence makes the computation equivalent to
    A+((B*C)/D)

    which is 10. Since B is defined as PIC9V9, it can't hold the high-order digit (1) and displays as zero.
  3. I'd have to see the pseudo-assembler generated by the online compiler to be certain, but my SWAG is that the compiler "knows" that B can't hold the result, and therefore doesn't actually compute it.
Bottom line: the online compiler is deliberately broken, to try to compensate for sloppy and/or ignorant coding; the MVS PL/I likewise tried to be smarter than the programmer.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 4:41 pm
by Robert Sample
Nikesh Rai, if you really want to understand what is happening, you need to click on the IBM Manuals link on the top right of this page, find the Enterprise COBOL Programming Guide manual, and read Appendix A Intermediate results and arithmetic precision completely. Broadly, the difference in results between the online and Enterprise COBOL compiler results is probably (but not guaranteed) due to the way B and C are handled -- IBM makes a copy of the values of B and C before the COMPUTE is executed and uses those copied values throughout the calculation. And if the online compiler does not handle intermediate results in the same fashion (and that is not likely) then your results are not going to be the same -- as you saw.

In general, any two compilers may generate different results (especially when running on different platforms) due to different ways of handling language constructs. Comparing the results from two different compilers may be instructive but is typically not indicative of anything significant. What is more important is to understand how the compiler you use the most produces its results.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 4:45 pm
by NicC
Having lost a load of hair recently over rounding with COMPUTE we have decided to avoid using rounding with COMPUTE. In some cases it would give different results with the same data (so many reruns trying to get it sorted!). Sometimes it appeared to truncate - but possibly didn't. Sometimes the results were different from doing a DIVIDE and then a MULTIPLY. This latter gave accurate results (according to Excel and Calculator).

It may well have been due to internal interim results as posted by Robert whilst I was writing the above.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 6:17 pm
by BillyBoyo
Nikesh Rai,

Akatsukami and Robert have given you information which will resolve your questions.

So, some advice. In a COMPUTE, I always use brackets/parentheses so that the compiler will achieve the calculation I want without me having ensure the order of coding, and without hoping that the next person does the same. Always use brackets/parentheses in COMPUTE unless trivial. If trivial, why use COMPUTE?

You must ensure that your output fields are big enough and have enough (including zero) decimal places to satisfy your requirement. IBM COBOL will just truncate the result. I think Akatsukami is correct about the other COBOL you used - the result was not stored in B because it would not fit.

IBM COBOL has a compile option, DIAGTRUNC, which can warn you of obvious potential truncation. It can be good to use as a beginner, but rather than relying on the compiler, it is much more important to know that all your fields are of the correct size. Then you don't need DIAGTRUNC. If doing deliberate truncation (which there are many reasons for) then DIAGTRUNC gets in the way :-)

From the section of the manual Robert suggested and from the description of COMPUTE with regard to precedence, work through an example with pencil and paper, behaving exactly as the compiler does.

Then have a go at this:

COMPUTE A ROUNDED = (( B / C ) + D) * 100


Assume that all fields are COMP-3/PACKED-DECIMAL with two decimal places and five before the (assumed) decimal point.

Make B 50, C 6, D 18.

First see what result the compiler produces. Then go through it on paper and see if you can work out how it "goes wrong". Let us know if you have questions, or get the answers.

EDIT. Thinking about it, initial value of C change to 6 from 3.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 6:20 pm
by BillyBoyo
Nic, that is called "Spreading FUD".

If you can still create the problem, bang it on here, and the bottom of it can be got to.

ROUNDED works. 100% of the time. All situations. However, if the COMPUTE is not coded so it gets the right answer, "ROUNDED" often gets the blame.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 6:58 pm
by Robert Sample
Mixing DIVIDE and MULTIPLY will give different results depending upon which is done first. And sometimes adding a digit to a PICTURE clause will change the results since the intermediate results depend upon the number of digits in the various operands. ROUNDED works, and works well, but requires a VERY thorough understanding of Appendix A of the Programming Guide to predict the results of any given set of operations.

Re: COMPUTE ROUNDED in COBOL

PostPosted: Wed Oct 16, 2013 10:03 pm
by nikesh_rai
Thanks to all the moderators for their replies.. :). I understood how the process is going on..

As what Robert suggested, I will read the manual

Re: COMPUTE ROUNDED in COBOL

PostPosted: Thu Oct 17, 2013 9:15 pm
by nikesh_rai
Hi Guys,

I have tested COMPUTE ROUNDED and it is working perfectly and as per expectation.. :) As I told earlier, I saw somewhere it was written that ROUNDED doesn't work with COMPUTE, is totally wrong.