Formatting money for print
Internally, money is a signed number with an implied decimal point:
PIC S9(5)V99 holding -1234.50 is just the digits 0123450 and a sign.
Nobody wants to read that on a statement. Edited pictures turn it into
something printable: leading zeros suppressed, commas, a real decimal
point, a currency sign, and a visible sign for negatives.
You MOVE a number into an edited field and the formatting happens during the move. Edited fields are for output only; you can't do arithmetic on them.
IDENTIFICATION DIVISION.
PROGRAM-ID. EDITDEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-AMT PIC S9(5)V99.
01 ED-ZERO-SUP PIC ZZ,ZZ9.99.
01 ED-ALL-Z PIC ZZ,ZZZ.ZZ.
01 ED-FLOAT-DOLLAR PIC $$$,$$9.99.
01 ED-CHECK PIC $**,**9.99.
01 ED-TRAIL-MINUS PIC ZZ,ZZ9.99-.
01 ED-FLOAT-MINUS PIC ---,--9.99.
01 ED-CR PIC ZZ,ZZ9.99CR.
01 ED-DATE PIC 99/99/9999.
PROCEDURE DIVISION.
MOVE -1234.5 TO WS-AMT
MOVE WS-AMT TO ED-ZERO-SUP ED-ALL-Z ED-FLOAT-DOLLAR
ED-CHECK ED-TRAIL-MINUS ED-FLOAT-MINUS ED-CR
DISPLAY "ZZ,ZZ9.99 [" ED-ZERO-SUP "]"
DISPLAY "ZZ,ZZZ.ZZ [" ED-ALL-Z "]"
DISPLAY "$$$,$$9.99 [" ED-FLOAT-DOLLAR "]"
DISPLAY "$**,**9.99 [" ED-CHECK "]"
DISPLAY "ZZ,ZZ9.99- [" ED-TRAIL-MINUS "]"
DISPLAY "---,--9.99 [" ED-FLOAT-MINUS "]"
DISPLAY "ZZ,ZZ9.99CR [" ED-CR "]"
MOVE 0 TO ED-ALL-Z
DISPLAY "ZZ,ZZZ.ZZ [" ED-ALL-Z "] (zero)"
MOVE 24092026 TO ED-DATE
DISPLAY "99/99/9999 [" ED-DATE "]"
STOP RUN.
Output:
ZZ,ZZ9.99 [ 1,234.50]
ZZ,ZZZ.ZZ [ 1,234.50]
$$$,$$9.99 [ $1,234.50]
$**,**9.99 [$*1,234.50]
ZZ,ZZ9.99- [ 1,234.50-]
---,--9.99 [ -1,234.50]
ZZ,ZZ9.99CR [ 1,234.50CR]
ZZ,ZZZ.ZZ [ ] (zero)
99/99/9999 [24/09/2026]
The symbols
| Symbol | Effect |
|---|---|
Z |
Digit; a leading zero becomes a space |
9 |
Digit, always printed. Put one before the . so zero prints 0.00 |
, . |
Inserted comma and decimal point (a comma in a suppressed zone becomes a space) |
* |
Like Z but fills with asterisks: cheque protection, so nobody can write digits in front |
$ |
One $ is fixed in place; a string of them floats to sit just left of the first digit |
- |
Minus shown for negatives, space for positives. Trailing, fixed leading, or floating (---,--9.99) |
+ |
Like - but shows + for positives too |
CR DB |
Two characters at the end, shown only for negatives (accounting style) |
B 0 / |
Insert a space, a zero or a slash (dates, account numbers) |
Two rules that catch people:
- No sign symbol, no sign.
$$$,$$9.99and$**,**9.99above printed -1234.50 as a positive amount. If a value can be negative, the picture needs-,+,CRorDB. - A floating string holds one digit fewer than its length. In
$$$,$$9.99the first$is reserved for the sign itself, so the field holds at most 5 integer digits (99,999.99). The same goes for---,--9.99. If the value doesn't fit, the high digits are silently lost.
BLANK WHEN ZERO
PIC ---,--9.99 BLANK WHEN ZERO prints spaces instead of 0.00. Summary
reports use it so that empty cells stand out: a page of 0.00s hides the
numbers that matter.
On the job
Size edited fields from the largest value the business can produce, not the test data: totals are bigger than details, and grand totals are bigger still. Truncated high-order digits on a financial report are a real, and embarrassing, production defect. Count the Zs.
Your task
A statement program prints each amount three ways. Write the three edited pictures so the output matches exactly.
Input (stdin): a count, then that many signed amounts such as
-1234.56 (never more than 99,999.99 either way).
Each output line is statement | cheque | ledger. The FILLERs are done;
replace the three PIC S9(5)V99 items:
| Column | Width | Style |
|---|---|---|
| statement | 12 | floating $, comma, 2 decimals, CR after negatives |
| cheque | 10 | $ fixed in column 1, asterisk fill, comma, 2 decimals, no sign |
| ledger | 10 | floating minus sign, comma, 2 decimals, blank when zero |
$1,234.56 | $*1,234.56 | 1,234.56
$1,234.56CR | $*1,234.56 | -1,234.56
$0.00 | $*****0.00 |
$0.05 | $*****0.05 | 0.05
$99,999.99 | $99,999.99 | 99,999.99
$7.00CR | $*****7.00 | -7.00