https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125615
Bug ID: 125615
Summary: [cobol] result of a floating-point COMPUTE is
truncated, not rounded
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: cobol
Assignee: unassigned at gcc dot gnu.org
Reporter: peeterjoot at protonmail dot com
Target Milestone: ---
Created attachment 64630
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64630&action=edit
standalone reproducer for the float rounding issue.
## Summary
When a `COMPUTE` (or any arithmetic statement) is evaluated in floating point —
i.e.
at least one operand is `COMP-1`/`COMP-2` or a floating-point literal — the
result
stored into a fixed-point receiver is **truncated** by gcobol. IBM Enterprise
COBOL
specifies that the result of a floating-point operation is **always rounded**,
independent of whether the `ROUNDED` phrase is present.
## Environment
- Compiler: `gcobol (Ubuntu 15.2.0-16ubuntu1) 15.2.0` (GCC COBOL front end)
- Platform: Linux x86-64 / aarch64
- No special compiler options.
## Reproducer
`float-compute-not-rounded.cob` (in this directory):
```cobol
01 SUBTOTAL PIC S9(9)V99 COMP-3 VALUE 70.95.
01 RATE COMP-1 VALUE 0.10.
01 RESULT PIC S9(9)V99 COMP-3 VALUE 0.
01 SHOW PIC ZZZ9.99.
...
COMPUTE RESULT = SUBTOTAL * RATE
MOVE RESULT TO SHOW
DISPLAY "RESULT=" SHOW
```
`RATE` is `COMP-1`, so `SUBTOTAL * RATE` is a floating-point operation.
`float(0.10) ≈ 0.100000001490116`, so `70.95 * float(0.10) ≈ 7.0950001`. The
edited
receiver `SHOW` (`PIC ZZZ9.99`) is used so the printed value reflects the
stored
`RESULT` without any numeric-DISPLAY de-editing differences.
```
gcobol -o fltround float-compute-not-rounded.cob && ./fltround
```
## Observed (gcobol 15.2.0)
```
RESULT= 7.09
```
The float result `7.0950001` was truncated to two fraction digits.
## Expected (IBM Enterprise COBOL)
```
RESULT= 7.10
```
The float result `7.0950001` rounds to `7.10` at the V99 receiver.
## Reference
IBM Enterprise COBOL for z/OS 6.5 Language Reference, SC27-8713-04, **ROUNDED
phrase**
(p.302):
> "When the size of the fractional result exceeds the number of places provided
> for
> its storage, truncation occurs unless ROUNDED is specified. … **In a
> floating-point
> arithmetic operation, the ROUNDED phrase has no effect; the result of a
> floating-point operation is always rounded.**"
So for a floating-point COMPUTE the result is rounded whether or not `ROUNDED`
is
written; gcobol truncates instead.
## Impact
Off-by-one-ULP monetary/scaled results whenever a fixed-point receiver is
assigned
from a floating-point expression without `ROUNDED`. The error propagates to
dependent
computations (e.g. a subsequent `grand-total = subtotal - discount`).