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`).

Reply via email to