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.
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.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.67Simpan berkasnya di direktori kerja, kompilasi dengan perintah berikut, lalu
jalankan ./aritmetika-verb.
# kompilasi program verb aritmetika
cobc -x aritmetika-verb.cblEnam 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.
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.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.21Kompilasi programnya dengan perintah berikut, lalu jalankan
./aritmetika-ukuran.
# kompilasi program pelindung size error
cobc -x aritmetika-ukuran.cblKeluarannya 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 / 3terpangkas 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#
- GnuCOBOL — Free Software Foundation — Situs proyek GnuCOBOL 3.2 yang digunakan untuk mengompilasi dan menjalankan seluruh contoh pada topik ini.
- IBM Enterprise COBOL for z/OS documentation — IBM — Dokumentasi resmi yang memuat bentuk ADD, SUBTRACT, MULTIPLY, DIVIDE, COMPUTE, ROUNDED, serta kondisi ON SIZE ERROR.