MOVE rules
MOVE copies data from a sending item to one or more receiving
items:
MOVE WS-INPUT-NAME TO WS-PRINT-NAME.
MOVE ZEROS TO WS-TOTAL WS-COUNT.
The sender is unchanged. What lands in the receiver depends on the receiver's picture, and COBOL never complains at run time if data gets lost. You need to know the rules cold.
Rule 1: alphanumeric receivers fill from the left
The data is copied starting at the leftmost position. If the receiver is longer, the rest is filled with spaces. If it is shorter, the extra characters are cut off on the right.
Rule 2: numeric receivers line up on the decimal point
The sending value is aligned by its decimal point (actual or implied V).
Missing positions are filled with zeros on both sides. Digits that
don't fit are cut off: high-order (leftmost) digits beyond the integer
part, and low-order digits beyond the decimals. There is no rounding.
The sign is kept only if the receiver has an S.
Rule 3: numbers to text
Moving an integer numeric field to an alphanumeric field copies its digits,
leading zeros included, and then follows rule 1. Moving a field with
decimals to an alphanumeric field is not allowed; the compiler rejects it
with invalid MOVE statement.
All three rules in one program:
IDENTIFICATION DIVISION.
PROGRAM-ID. MOVES.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-SOURCE-TEXT PIC X(6) VALUE "DUBLIN".
01 WS-SHORT PIC X(3).
01 WS-LONG PIC X(10).
01 WS-SOURCE-AMT PIC 9(4)V99 VALUE 1234.56.
01 WS-SMALL-AMT PIC 9(2)V9.
01 WS-BIG-AMT PIC 9(6)V999.
01 WS-COUNT PIC 9(3) VALUE 42.
01 WS-COUNT-TEXT PIC X(5).
PROCEDURE DIVISION.
MOVE WS-SOURCE-TEXT TO WS-SHORT.
MOVE WS-SOURCE-TEXT TO WS-LONG.
DISPLAY "SHORT [" WS-SHORT "]".
DISPLAY "LONG [" WS-LONG "]".
MOVE WS-SOURCE-AMT TO WS-SMALL-AMT WS-BIG-AMT.
DISPLAY "SMALL [" WS-SMALL-AMT "]".
DISPLAY "BIG [" WS-BIG-AMT "]".
MOVE WS-COUNT TO WS-COUNT-TEXT.
DISPLAY "TEXT [" WS-COUNT-TEXT "]".
STOP RUN.
SHORT [DUB]
LONG [DUBLIN ]
SMALL [34.5]
BIG [001234.560]
TEXT [042 ]
Look hard at SMALL: 1234.56 became 34.5. The thousands and hundreds
vanished off the left, the last decimal off the right, and the program
carried on without a murmur. With money, that is how a 1,234.56 payment
turns into 34.50.
The compiler only warns about literals
MOVE "ABCDEF" TO WS-SHORT or MOVE 12345 TO WS-SMALL-AMT produces a
value size exceeds data size warning, because the compiler can see
the literal. Field-to-field moves like the ones above compile with no
warning at all. Only you can check that receivers are big enough.
Moving text into numbers
MOVE "0042" TO WS-NUM treats the characters as an unsigned integer. If
the text isn't all digits (spaces, letters), the numeric field ends up
holding invalid data, and arithmetic on it will fail later. Validate input
before moving it into numeric fields; you will learn how in the conditions
module.
On the job
When a field is widened (say an amount grows from 9(5)V99 to
9(7)V99), every field it is moved to must be widened too, in every
program that uses it. Missing one is a classic production defect.
Search for every MOVE that touches the field.
Your task
The price-list conversion program is losing data. For the input
WIDGET-00042
12345.67
-12.50
it prints CODE: [WIDGET-0], a price of 345.67 and an adjustment of
012.5 with no minus sign. Product codes are being cut short, prices
over 999.99 lose their thousands, and credits turn into charges.
Fix the pictures of the three OUT- fields so each can hold every
value its IN- field can: the same size, the same number of decimals,
and a sign where the input has one. Don't change the PROCEDURE
DIVISION. The correct output is:
CODE: [WIDGET-00042]
PRICE: 012345.67
ADJ: -0012.50