Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How COBOL handles division rounding by default?

Tags:

rounding

cobol

In COBOL what is the result of

COMPUTE RESULT1  = 97 / 100
COMPUTE RESULT2  = 50 / 100
COMPUTE RESULT3  = 32 / 100
COMPUTE RESULT4  = -97 / 100
COMPUTE RESULT5  = -50 / 100
COMPUTE RESULT6  = -32 / 100

When RESULT1/2/3 are:

  1. PIC S9(4)
  2. PIC S9(4)V9
  3. PIC S9(4)V99

Or, in other words, what is the default rounding mode for COBOL divisions?

Edit: What happens with negative values?

Even "discard" is sort of a rounding mode, is it equivalent to rounding towards negative infinity or towards zero?

like image 334
RSFalcon7 Avatar asked May 13 '15 12:05

RSFalcon7


1 Answers

COBOL does no rounding, unless you tell it to.

What it does do, if you don't tell it to do rounding, is low-order truncation. Some people may prefer to term that something else, it doesn't really matter, the effect is the same. Truncation.

Negative values are dealt with in the same way as positive values (retain a significant digit beyond what is required for the final result, and add one to that (also see later explanation): -0.009 would, to two decimal places, round to -0.01; -0.004 would round to -0.00.

If you specify no decimal places for a field, any fractional part will be simply discarded.

So, when all the targets of your COMPUTEs are 9(4), they will all contain zero, including the negative values.

When all the targets of your COMPUTEs are 9(4)V9, without rounding, they will contain 0.9, 0.5 and 0.3 respectively with the low-order (from the second decimal digit) decimal part being truncated.

And when all the targets of your COMPUTEs are 9(4)V99, they will contain 0.97, 0.50 and 0.32 with the low-order decimal part beyond that being truncated.

You do rounding in the language by using the ROUNDED phrase for the result of any arithmetic verb (ADD, SUBTRACT, MULTIPLY, DIVIDE, COMPUTE).

ADD some-name                 some-other-name   GIVIING                some-result
                                ROUNDED

COMPUTE some-result ROUNDED   = some-name
                              + some-other-name

The above are equivalent to each other.

To the 1985 Standard, ROUNDED takes the final result with one extra decimal place and adjusts the actual field with the defined decimal places by adding "one" at the smallest possible unit (for V99, it will add one hundredth, at V999 it will add one thousandth, at no decimal places it will add one, with any scaling amount (see PICture character P) it will add one).

You can consider the addition of one to be made to an absolute value, with the result retaining the original sign. Or you can consider it as done in any other way which achieves the same result. The Standard describes the rounding, the implementation meets the Standard in whatever way it likes. My description is a description for human understanding. No compiler need implement it in the way I have described, but logically the results will be the same.

Don't get hung up on how it is implemented.

The 2014 Standard, superseding the 2002 Standard, has further options for rounding, which for the 85 Standard you'd have to code for (very easy use of REDEFINES).

`ROUNDED` `MODE IS` `AWAY-FROM-ZERO` `NEAREST-AWAY-FROM-ZERO` `NEAREST-EVEN` `NEAREST-TOWARD-ZERO` `PROHIBITED` `TOWARD-GREATER` `TOWARD-LESSER TRUNCATION`

Only one "mode" may be specified at a time, and the default if MODE IS is not specified is TRUNCATION, establishing backward-compatibility (and satisfying those who feel the everything is rounding of some type.

The PROHIBITED option is interesting. If the result field has, for instance, two decimal places, then POHIBITED requires that the calculated result has only two high-order decimal places and all lower-order values are zero.

It is important to note with a COMPUTE that only the final result is rounded, intermediate results are not. If you need intermediate rounding, you need one COMPUTE (or other arithmetic verb) per rounded result.

like image 101
Bill Woodger Avatar answered Oct 19 '22 17:10

Bill Woodger