COBOL and $2,020,202.02

Over the years, in fact even in the past year or two I would see on the News some person either getting a bill or a check for some ridiculous amount of money that would be in the form $2020202020… .02.

If you ever see this you know it was (almost certainly) a programming mistake made in COBOL. Most COBOL programmers have made this bonehead mistake and I am no exception.

The problem is caused by the way COBOL programmers typically initialize a record. Given this little program:

       identification division.
       program-id.
           mistake.
       
       data division.
       working-storage section.
      
      * *** Input record, typically maintained on disk/tape somewhere.
       01  dr-datarec.
           03  dr-name                 pic x(20).
           03  dr-amount               pic s9(7)v99, comp-3.

      * *** print record, sent to a line printer.
       01  dt-detail.
           03  dt-name                 pic x(20).
           03  filler                  pic x.
           03  dt-amount               pic z,zzz,zz9.99.            
       
       procedure division.
       
           move spaces                 to dr-datarec.
           move "test"                 to dr-name.
           move 100                    to dr-amount.

           move spaces                 to dt-detail.
           move dr-name                to dt-name.
           move dr-amount              to dt-amount.

           display dt-detail.
       
           stop run.

In this program, dr-datarec is the input record. Normally it would be coming from disk somewhere. For this simple test, I am creating it by hand.

Once the input record is obtained, calculations are done, and the record is then printed using dt-detail.

The problem is in how dr-datarec is created. Note how I move spaces to it to initialize it. This was a common method of initializing a record.

By doing so, all PIC X fields have spaces in them. BUT, all COMP-3 fields are initialized as well, just not to zero. The programmer has to be sure to create valid values for any COMP-3 field. In the test program, this is properly done:

           move spaces                 to dr-datarec.
           move "test"                 to dr-name.
           move 100                    to dr-amount.

dr-amount clearly has 100 in it. When I run the program I get:

./mistake 
test                       100.00

What if a coding mistake is made and dr-amount is not initialized properly?

It still contains ASCII spaces. That would be HEX 20 or binary 0010 0000.

COMP-3 stores digits as 4 bit “nibbles”, so a single space would appear as the digits 20. If you have 9 digits, as dr-amount has, it requires 10 nibbles of storage (9 nibbles for the digits and one for the sign) OR 5 bytes.

The MOVE SPACES to DR-DATAREC would result in 5 spaces being stored in the field or the hex value of 2020202020. This is interpreted as 2,020,202.02 if you attempt to use the uninitialized variable.

If I comment out the initialization of dr-amount, I can force this error:

           move spaces                 to dr-datarec.
           move "test"                 to dr-name.
     *     move 100                    to dr-amount.

Now when I run the program:

./mistake 
test                 2,020,202.02

COBOL 85 introduced the INITIALIZE verb to correct this problem. Rather than moving spaces to the record, you initialize it and it will move spaces to alphanumeric fields and zeros to numeric fields:

      *    move spaces                 to dr-datarec.
           initialize dt-detail.
           move "test"                 to dr-name.
      *    move 100                    to dr-amount.

results in:

./mistake 
test                         0.00

So the next time you see a poor widow charged $2,020,202.02 on their utility bill, you will know exactly how it happened!

Update

The above example assumes an ASCII machine. If run on an EBCDIC-based machine (IBM), SPACE is HEX 40 and you would see $4,040,404.04 instead.

[https://www.reddit.com/r/programming/comments/jo4c59/cobol_and_202020202/]

This entry was posted in c-gnuCOBOL and tagged . Bookmark the permalink.

2 Responses to COBOL and $2,020,202.02

  1. Planters says:

    shared on the growing and increasingly vibrant COBOL Programmers Facebook Group. Be good to see you there https://www.facebook.com/groups/COBOLProgrammers/

  2. Pingback: COBOL и $2 020 202,02 | | Факты,Новости Науки и Цифровых Технологий

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.