COBOL dan $ 2.020 202,02

Dalam beberapa tahun terakhir, bahkan dalam satu atau dua tahun terakhir, saya kadang-kadang menemukan berita bahwa seseorang menerima faktur atau cek dengan jumlah yang konyol yaitu 2.020.202 dolar ... dan 02 sen.



Jika Anda melihat ini, itu (hampir pasti) kesalahan pemrograman COBOL. Kebanyakan pemrogram COBOL membuat kesalahan bodoh ini, dan saya tidak terkecuali.



Masalahnya disebabkan oleh cara kami biasanya menginisialisasi rekaman. Mari kita ambil program kecil seperti ini:



       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.


Dalam program ini, masukan catatan dr-datarec. Biasanya ini berasal dari suatu tempat di disk, tetapi untuk pengujian sederhana ini dibuat secara manual.



Setelah record input diterima, komputasi dilakukan dan kemudian record tersebut dikeluarkan menggunakan dt-detail.



Masalahnya adalah bagaimana record dibuat dr-datarec. Perhatikan bagaimana spasi dipindahkan untuk memulainya. Ini adalah metode tipikal untuk menginisialisasi record.



Jadi, ada spasi di semua bidang PIC X. Tapi! Semua bidang COMP-3 juga diinisialisasi, tetapi tidak sampai nol. Pemrogram harus yakin bahwa nilai yang valid dihasilkan untuk semua bidang COMP-3. Program pengujian melakukannya dengan benar:



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


dr-amountJelas ada 100 di lapangan. Setelah dimulai ternyata:



./mistake 
test                       100.00


Bagaimana jika ada kesalahan encoding dan rekaman dr-amounttidak diinisialisasi dengan benar?



Masih ada ruang ASCII di sana. Ini adalah nilai heksadesimal 20 atau biner 0010 0000.



COMP-3 menyimpan digit sebagai camilan empat-bit, jadi satu spasi ditampilkan sebagai 20. Jika Anda memiliki 9 digit seperti dr-jumlah, maka ini membutuhkan 10 camilan memori (9 camilan untuk digit dan satu untuk tanda) atau 5 byte.



Memindahkan spasi dr-datarecakan menghasilkan 5 spasi atau nilai heksadesimal 2020202020 disimpan di bidang ini. Jika Anda mencoba menggunakan variabel yang tidak diinisialisasi, itu akan ditafsirkan sebagai 2020 202.02.



Jika Anda mengomentari inisialisasi dr-amount, Anda dapat memaksakan kesalahan ini:



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


Sekarang saat memulai program:



./mistake 
test                 2,020,202.02


Untuk memperbaiki masalah ini, COBOL 85 memperkenalkan kata kerja INITIALIZE. Alih-alih memindahkan spasi ke rekaman, Anda menginisialisasinya, dan ini akan memindahkan spasi ke bidang alfanumerik dan nol ke bidang numerik:



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


Hasil eksekusi:



./mistake 
test                         0.00


Jadi, lain kali Anda melihat seorang janda miskin yang mendapat tagihan listrik sebesar $ 2.020.202,02, Anda akan tahu persis apa yang terjadi!



All Articles