Verb Aritmetika

ADD, SUBTRACT, MULTIPLY, DIVIDE, dan COMPUTE dengan ON SIZE ERROR untuk aritmetika desimal eksak.

Daftar isi

Topik ini membahas lima verb aritmetika COBOL, yaitu ADD, SUBTRACT, MULTIPLY, DIVIDE, dan COMPUTE, beserta klausa ROUNDED dan pelindung ON SIZE ERROR. Pembahasan menegaskan sifat aritmetika desimal eksak yang menjadikan COBOL cocok untuk data keuangan, termasuk alasan mengapa tipe floating point biner bukan alat yang tepat untuk nilai uang. Setiap bentuk verb didemonstrasikan dengan program nyata pada GnuCOBOL 3.2 dan keluaran aslinya.

Bentuk dasar lima verb aritmetika#

Setiap verb aritmetika menyimpan hasilnya ke field tujuan setelah seluruh operan sumber dihitung, sehingga field yang menjadi operan sekaligus tujuan tidak mengganggu perhitungannya sendiri. ADD menyediakan dua bentuk utama, yaitu ADD a b GIVING c yang menulis jumlah a dan b ke c, serta ADD a TO b yang menjumlahkan a ke atas isi b dan menulis hasilnya kembali ke b. SUBTRACT mengurangkan dengan bentuk SUBTRACT a FROM b GIVING c. MULTIPLY menggunakan kata BY, sedangkan DIVIDE menggunakan INTO untuk pembagian b / a dan BY untuk pembagian a / b. Klausa REMAINDER menyimpan sisa pembagian bulat pada field tersendiri.

Program berikut memuat semua bentuk tersebut beserta COMPUTE dan ROUNDED.

cobol aritmetika-verb.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ARIT-VERB.
      *--------------------------------------------------------------
      * Kelima verb aritmetika beserta presedens COMPUTE dan klausa
      * ROUNDED.
      *--------------------------------------------------------------
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  HASIL      PIC 9(4).
       01  SISA       PIC 9(3).
       01  B          PIC 9(4) VALUE 175.
       01  H-DES      PIC 9(3)V99.
       01  TAMPIL     PIC Z(3)9.99.
       PROCEDURE DIVISION.
       DEMO-ADD.
           ADD 250 175 GIVING HASIL
           DISPLAY "ADD 250 175 GIVING HASIL : " HASIL
           MOVE 175 TO B
           ADD 250 TO B
           DISPLAY "ADD 250 TO B, B mula-mula 175 : " B.
       DEMO-SUBTRACT.
           SUBTRACT 75 FROM 250 GIVING HASIL
           DISPLAY "SUBTRACT 75 FROM 250     : " HASIL.
       DEMO-MULTIPLY.
           MULTIPLY 12 BY 8 GIVING HASIL
           DISPLAY "MULTIPLY 12 BY 8         : " HASIL.
       DEMO-DIVIDE.
           DIVIDE 7 INTO 100 GIVING HASIL REMAINDER SISA
           DISPLAY "DIVIDE 7 INTO 100        : " HASIL " sisa " SISA
           DIVIDE 100 BY 4 GIVING HASIL
           DISPLAY "DIVIDE 100 BY 4          : " HASIL.
       DEMO-COMPUTE.
           COMPUTE HASIL = 2 + 3 * 4
           DISPLAY "COMPUTE 2 + 3 * 4        : " HASIL
           COMPUTE HASIL = (2 + 3) * 4
           DISPLAY "COMPUTE (2 + 3) * 4      : " HASIL
           COMPUTE HASIL = 2 ** 10
           DISPLAY "COMPUTE 2 ** 10          : " HASIL.
       DEMO-ROUNDED.
           COMPUTE H-DES = 2 / 3
           MOVE H-DES TO TAMPIL
           DISPLAY "COMPUTE 2 / 3 tanpa ROUNDED : " TAMPIL
           COMPUTE H-DES ROUNDED = 2 / 3
           MOVE H-DES TO TAMPIL
           DISPLAY "COMPUTE 2 / 3 ROUNDED       : " TAMPIL.
       AKHIR-PROGRAM.
           STOP RUN.
text Keluaran
ADD 250 175 GIVING HASIL : 0425
ADD 250 TO B, B mula-mula 175 : 0425
SUBTRACT 75 FROM 250     : 0175
MULTIPLY 12 BY 8         : 0096
DIVIDE 7 INTO 100        : 0014 sisa 002
DIVIDE 100 BY 4          : 0025
COMPUTE 2 + 3 * 4        : 0014
COMPUTE (2 + 3) * 4      : 0020
COMPUTE 2 ** 10          : 1024
COMPUTE 2 / 3 tanpa ROUNDED :    0.66
COMPUTE 2 / 3 ROUNDED       :    0.67

Simpan berkasnya di direktori kerja, kompilasi dengan perintah berikut, lalu jalankan ./aritmetika-verb.

bash
# kompilasi program verb aritmetika
cobc -x aritmetika-verb.cbl

Enam baris pertama keluaran memperlihatkan bentuk dasarnya. Pembagian DIVIDE 7 INTO 100 menghasilkan 14 dengan sisa 2 pada field SISA, sedangkan DIVIDE 100 BY 4 langsung menghasilkan 25 tanpa sisa. Perhatikan bahwa nilai tampil dengan nol pengisi milik picture, misalnya 0425 pada field PIC 9(4). Bentuk tampilan yang rapi diperoleh dari picture hasil edit, bukan dari verb aritmetikanya.

COMPUTE, presedens, dan pembulatan ROUNDED#

COMPUTE menggabungkan kelima operasi dalam satu ekspresi dengan operator +, -, *, /, dan **. Presedensnya mengikuti kebiasaan matematika, yaitu pangkat ** paling tinggi, dilanjutkan perkalian dan pembagian, lalu penjumlahan dan pengurangan, dan tanda kurung mengesampingkan presedens tersebut. Tiga baris COMPUTE pada keluaran menunjukkan efeknya. Ekspresi 2 + 3 * 4 menghasilkan 14 karena perkalian dikerjakan lebih dahulu, bentuk (2 + 3) * 4 menghasilkan 20, dan 2 ** 10 menghasilkan 1024.

Klausa ROUNDED menentukan perlakuan atas digit yang terpangkas saat hasil dimasukkan ke field tujuan. Tanpa klausa tersebut, digit berlebih dipotong tanpa pembulatan, sedangkan dengan ROUNDED hasil dibulatkan ke digit terdekat. Dua baris terakhir keluaran membandingkannya pada pembagian 2 / 3 ke field PIC 9(3)V99. Tanpa ROUNDED hasilnya 0.66, sedangkan dengan ROUNDED hasilnya 0.67 karena digit ketiga bernilai 6 membulatkan digit sebelumnya ke atas. Untuk data keuangan, tentukan klausa ini secara sadar pada setiap pembagian yang hasilnya tidak bulat.

Pelindung ON SIZE ERROR#

Kondisi size error terjadi apabila hasil perhitungan tidak muat dalam picture field tujuan, misalnya 145 yang harus masuk ke PIC 9(2) yang hanya menampung sampai 99. Tanpa pelindung, isi field tujuan menjadi tidak terdefinisi dan program berlanjut dengan data yang salah. Klausa ON SIZE ERROR mencegahnya. Apabila kondisi tersebut terjadi, field tujuan dibiarkan tidak berubah dan pernyataan pada cabangnya dieksekusi, sedangkan cabang NOT ON SIZE ERROR menampung jalur normal ketika hasil muat. Pemisah END-ADD menutup cakupan kedua cabang tersebut.

Program berikut memicu kedua cabang dengan dua perhitungan yang hasilnya sengaja dibuat berbeda.

cobol aritmetika-ukuran.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ARIT-UKUR.
      *--------------------------------------------------------------
      * ON SIZE ERROR dan NOT ON SIZE ERROR beserta sifat eksak
      * aritmetika desimal COBOL.
      *--------------------------------------------------------------
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  HASIL      PIC 9(2).
       01  H-DES      PIC 9V99.
       01  TAMPIL     PIC 9.99.
       PROCEDURE DIVISION.
       DEMO-SIZE-ERROR.
           ADD 50 95 GIVING HASIL
               ON SIZE ERROR
                   DISPLAY "ADD 50 95 ke PIC 9(2) : SIZE ERROR"
               NOT ON SIZE ERROR
                   DISPLAY "ADD 50 95 ke PIC 9(2) : Hasil " HASIL
           END-ADD
           ADD 50 45 GIVING HASIL
               ON SIZE ERROR
                   DISPLAY "ADD 50 45 ke PIC 9(2) : SIZE ERROR"
               NOT ON SIZE ERROR
                   DISPLAY "ADD 50 45 ke PIC 9(2) : Hasil " HASIL
           END-ADD.
       DEMO-DESIMAL-EKSAK.
           COMPUTE H-DES = 0.1 + 0.2
           MOVE H-DES TO TAMPIL
           DISPLAY "0.1 + 0.2   = " TAMPIL
           COMPUTE H-DES = 1.10 * 1.10
           MOVE H-DES TO TAMPIL
           DISPLAY "1.10 * 1.10 = " TAMPIL.
       AKHIR-PROGRAM.
           STOP RUN.
text Keluaran
ADD 50 95 ke PIC 9(2) : SIZE ERROR
ADD 50 45 ke PIC 9(2) : Hasil 95
0.1 + 0.2   = 0.30
1.10 * 1.10 = 1.21

Kompilasi programnya dengan perintah berikut, lalu jalankan ./aritmetika-ukuran.

bash
# kompilasi program pelindung size error
cobc -x aritmetika-ukuran.cbl

Keluarannya menunjukkan ADD 50 95 memicu cabang ON SIZE ERROR karena hasilnya 145 melampaui batas 99, sedangkan ADD 50 45 yang menghasilkan 95 mengalir ke cabang NOT ON SIZE ERROR dan menampilkan isinya. Sertakan pelindung ini pada setiap perhitungan yang batas atas operannya tidak dapat dijamin, terutama sebelum hasil ditulis ke field dengan ukuran tetap.

Desimal eksak tanpa float#

Aritmetika COBOL bekerja pada digit desimal, bukan pada bilangan biner pecahan. Huruf V dan jumlah digit desimal pada picture menetapkan skala, sehingga nilai seperti 0.30 direpresentasikan tepat sebagai digit 030 dengan skala dua. Dua baris terakhir keluaran program aritmetika-ukuran membuktikannya. Perhitungan 0.1 + 0.2 menghasilkan 0.30 persis, dan 1.10 * 1.10 menghasilkan 1.21 persis. Pada aritmetika floating point biner, dua perhitungan yang sama menghasilkan 0.30000000000000004 karena sebagian besar pecahan desimal tidak dapat direpresentasikan sempurna dalam basis dua.

Tipe USAGE COMP-1 dan COMP-2 pada COBOL memang berupa floating point biner, tetapi keduanya bukan alat yang tepat untuk nilai uang. Keduanya berguna untuk perhitungan ilmiah yang toleran terhadap selisih kecil, sedangkan saldo, bunga, dan pajak menuntut ketepatan hingga digit terakhir. Pertahankan USAGE DISPLAY atau COMP-3 untuk data uang, dan biarkan skala picture menangani desimalnya.

Kesalahan umum#

  • Menampilkan field hasil mentah. Field PIC 9(4) menampilkan 0042, yang terlihat salah padahal isinya benar. Pindahkan hasil ke picture hasil edit sebelum ditampilkan.
  • Melupakan ROUNDED pada pembagian. Hasil 2 / 3 terpangkas menjadi 0.66 dan selisihnya menumpuk pada penjumlahan panjang. Tambahkan klausa ROUNDED pada field tujuan setiap pembagian desimal.
  • Membiarkan field tujuan tanpa pelindung. Satu operan yang tidak terduga memicu size error tanpa pesan apa pun dan mencemari hasil perhitungan berikutnya. Sertakan ON SIZE ERROR pada perhitungan yang batasnya tidak terjamin.

Ringkasan#

  • ADD, SUBTRACT, MULTIPLY, dan DIVIDE menyediakan bentuk GIVING untuk field tujuan tersendiri serta bentuk TO, FROM, dan BY yang menulis hasil kembali ke operannya.
  • COMPUTE menggabungkan operasi dengan presedens **, lalu * dan /, lalu + dan -, dan klausa ROUNDED membulatkan digit terpangkas.
  • Klausa ON SIZE ERROR melindungi field tujuan dari hasil yang meluap dengan menjaga isinya dan menjalankan cabang penanganannya.
  • Aritmetika COBOL eksak karena berbasis digit desimal dengan skala picture, sehingga tipe floating point biner seperti COMP-1 dan COMP-2 tidak digunakan untuk nilai uang.

Referensi#