Klausa USAGE menentukan cara sebuah item data disimpan di dalam memori, dan pilihan itu memengaruhi ukuran, keterbacaan berkas, serta cara item diperlakukan pada aritmetika. Topik ini membahas tiga USAGE yang paling sering digunakan, yaitu DISPLAY dengan satu digit per byte, COMP dengan penyimpanan biner, dan COMP-3 dengan desimal paket, lengkap dengan jebakan penyalinan grup yang melintasi USAGE yang berbeda.
USAGE DISPLAY satu digit per byte#
Tanpa klausa USAGE, item data menggunakan USAGE DISPLAY, yaitu penyimpanan satu byte per posisi picture dengan setiap digit tersimpan sebagai karakter. Ukurannya mudah dihitung, yaitu jumlah posisi picture sama dengan jumlah byte, dan kebenarannya dapat dibuktikan dengan FUNCTION LENGTH yang mengembalikan ukuran item dalam byte. Simbol V dan tanda yang tersimpan dalam digit tidak menambah byte, sedangkan klausa SIGN TRAILING SEPARATE menambah satu byte untuk karakter tandanya.
IDENTIFICATION DIVISION.
PROGRAM-ID. UKURAN-DISPLAY.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 KODE-PRODUK PIC 9(5).
01 NAMA-BARANG PIC X(10).
01 HARGA PIC S9(7)V99.
01 HARGA-STS PIC S9(7)V99 SIGN TRAILING SEPARATE.
01 PANJANG PIC Z9.
PROCEDURE DIVISION.
COMPUTE PANJANG = FUNCTION LENGTH(KODE-PRODUK)
DISPLAY "PIC 9(5) : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(NAMA-BARANG)
DISPLAY "PIC X(10) : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(HARGA)
DISPLAY "PIC S9(7)V99 : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(HARGA-STS)
DISPLAY "PIC S9(7)V99 +STS : " PANJANG " byte"
STOP RUN.PIC 9(5) : 5 byte
PIC X(10) : 10 byte
PIC S9(7)V99 : 9 byte
PIC S9(7)V99 +STS : 10 byteHasil pengukuran cocok dengan aturan satu byte per posisi. Field PIC S9(7)V99 berukuran 9 byte karena memuat tujuh digit dan dua digit desimal, sedangkan simbol V hanya menandai posisi logis titik desimal dan tidak menempati byte. Versi dengan SIGN TRAILING SEPARATE menjadi 10 byte karena karakter tandanya disimpan sebagai satu karakter terpisah di ujung field.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./ukuran-display.
# kompilasi program menjadi eksekutabel
cobc -x ukuran-display.cblCOMP biner dan COMP-3 desimal paket#
USAGE COMP menyimpan bilangan sebagai biner utuh, dan GnuCOBOL menempatkan 1 sampai 4 digit pada 2 byte, 5 sampai 9 digit pada 4 byte, serta 10 sampai 18 digit pada 8 byte. USAGE COMP-3, yang juga disebut desimal paket atau packed decimal, menyimpan dua digit dalam satu byte ditambah satu nibel (nibble) tanda di ujung, sehingga ukurannya adalah byte untuk digit. Nilai 123.45 dalam PIC 9(5)V99 COMP-3 tersimpan sebagai empat byte yang memuat digit 0012345 dan nibel tanda F. COMP, COMP-4, dan COMP-5 sama-sama biner pada GnuCOBOL, sedangkan COMP-1 dan COMP-2 adalah bilangan pecahan floating point 4 dan 8 byte yang tidak tepat untuk nilai uang karena pecahan desimal tidak pernah eksak dalam biner.
IDENTIFICATION DIVISION.
PROGRAM-ID. UKURAN-USAGE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 BIN-KECIL PIC 9(4) COMP VALUE 45.
01 BIN-SEDANG PIC 9(7) COMP VALUE 1234567.
01 BIN-BESAR PIC 9(12) COMP VALUE 123456789012.
01 PAKET-KECIL PIC 9(3) COMP-3 VALUE 451.
01 PAKET-BESAR PIC S9(5)V99 COMP-3 VALUE 123.45.
01 PANJANG PIC Z9.
PROCEDURE DIVISION.
COMPUTE PANJANG = FUNCTION LENGTH(BIN-KECIL)
DISPLAY "PIC 9(4) COMP : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(BIN-SEDANG)
DISPLAY "PIC 9(7) COMP : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(BIN-BESAR)
DISPLAY "PIC 9(12) COMP : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(PAKET-KECIL)
DISPLAY "PIC 9(3) COMP-3 : " PANJANG " byte"
COMPUTE PANJANG = FUNCTION LENGTH(PAKET-BESAR)
DISPLAY "PIC S9(5)V99 C-3 : " PANJANG " byte"
DISPLAY BIN-KECIL " " BIN-SEDANG " " BIN-BESAR
DISPLAY PAKET-KECIL " " PAKET-BESAR
STOP RUN.PIC 9(4) COMP : 2 byte
PIC 9(7) COMP : 4 byte
PIC 9(12) COMP : 8 byte
PIC 9(3) COMP-3 : 2 byte
PIC S9(5)V99 C-3 : 4 byte
0045 1234567 123456789012
451 +00123.45Dua baris terakhir menunjukkan bahwa DISPLAY tetap merender nilai COMP dan COMP-3 sebagai desimal yang terbaca, sehingga penyimpanan biner tidak mengubah cara nilainya ditampilkan. Tanda plus pada +00123.45 berasal dari field COMP-3 bertanda yang tampil dengan tandanya. Tabel berikut merangkum ukuran yang terverifikasi melalui pengukuran di atas dan juga tercantum pada dokumentasi GnuCOBOL maupun IBM.
| Picture | USAGE | Digit | Ukuran terukur |
|---|---|---|---|
9(4) | COMP | 4 | 2 byte |
9(7) | COMP | 7 | 4 byte |
9(12) | COMP | 12 | 8 byte |
9(3) | COMP-3 | 3 | 2 byte |
S9(5)V99 | COMP-3 | 7 | 4 byte |
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./ukuran-usage.
# kompilasi program menjadi eksekutabel
cobc -x ukuran-usage.cblJebakan MOVE grup antar USAGE#
MOVE grup menyalin byte tanpa konversi, dan salinan itu menjadi kacau ketika grup asal berisi item COMP-3 sedangkan grup tujuan berisi item DISPLAY. Program berikut menyalin grup berisi item COMP-3 ke grup berisi item DISPLAY, lalu memeriksa byte hasil salinan satu per satu dengan FUNCTION ORD yang mengembalikan nomor karakter pada urutan kolasi.
IDENTIFICATION DIVISION.
PROGRAM-ID. GRUP-USAGE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 GRUP-PAKET.
05 TOTAL-PESERTA PIC 9(5)V99 COMP-3 VALUE 123.45.
01 GRUP-CETAK.
05 TOTAL-TAMPIL PIC 9(5)V99.
01 INDEKS PIC 9.
01 UKUR-BYTE PIC ZZZ9.
PROCEDURE DIVISION.
MOVE GRUP-PAKET TO GRUP-CETAK
PERFORM VARYING INDEKS FROM 1 BY 1 UNTIL INDEKS > 7
COMPUTE UKUR-BYTE = FUNCTION ORD(TOTAL-TAMPIL(INDEKS:1))
DISPLAY "byte " INDEKS ": " UKUR-BYTE
END-PERFORM
MOVE TOTAL-PESERTA TO TOTAL-TAMPIL
DISPLAY "Salinan elementer : [" TOTAL-TAMPIL "]"
STOP RUN.byte 1: 1
byte 2: 19
byte 3: 53
byte 4: 96
byte 5: 33
byte 6: 33
byte 7: 33
Salinan elementer : [00123.45]Nomor karakter pada keluaran dikurangi satu menghasilkan kode byte sesungguhnya, sehingga empat byte pertama terbaca sebagai 0, 18, 52, dan 95. Kode 52 dan 95 adalah karakter 4 dan _, sedangkan kode 0 dan 18 adalah karakter kontrol yang tidak tercetak di terminal. Byte paket 123.45 memang tersalin apa adanya, sehingga field PIC 9(5)V99 yang menerima byte bukan digit menampilkan isi yang kacau. Tiga byte terakhir bernilai spasi karena grup tujuan lebih besar dan MOVE grup mengisi sisanya dengan spasi.
Baris terakhir keluaran memperlihatkan cara penyalinan yang benar. MOVE elementer dari TOTAL-PESERTA ke TOTAL-TAMPIL memicu konversi karena keduanya item elementer bertipe numeric, sehingga 123.45 tampil benar sebagai 00123.45. Alternatif lain adalah memindahkan nilai ke field hasil edit agar tampilannya langsung terformat.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./grup-usage.
# kompilasi program menjadi eksekutabel
cobc -x grup-usage.cblKonsekuensi pemilihan USAGE#
Ketiga USAGE menghasilkan aritmetika desimal yang eksak karena semuanya bekerja pada bilangan tetap (fixed point), berbeda dari floating point yang menyimpan pecahan secara hampiran. Pembedanya ada pada ukuran penyimpanan, keterbacaan data, dan kecepatan pemrosesan, sebagaimana dirangkum tabel berikut untuk field PIC 9(7).
| Aspek | DISPLAY | COMP | COMP-3 |
|---|---|---|---|
| Ukuran 7 digit | 7 byte | 4 byte | 4 byte |
| Terbaca langsung sebagai teks | ya | tidak | tidak |
| Aritmetika desimal eksak | ya | ya | ya |
USAGE DISPLAY menghasilkan berkas terbesar tetapi isinya dapat dibaca dengan editor teks, sehingga cocok untuk berkas laporan dan data yang diperiksa manusia. COMP dan COMP-3 memangkas ukuran berkas serta mengurangi beban konversi saat aritmetika berat, dan COMP-3 menjadi pilihan lazim untuk nilai uang karena penataan digitnya persis mengikuti notasi desimal. Konsekuensi terpentingnya terletak pada berkas, karena record yang ditulis dengan suatu USAGE harus dibaca kembali dengan definisi yang sama persis, termasuk USAGE-nya.
Kesalahan umum#
- Menyalin grup yang berisi item COMP-3 atau COMP ke grup berisi item DISPLAY. Byte paket dan biner tersalin mentah sehingga field tujuan berisi data tak sah, sebagaimana ditunjukkan program
grup-usage.cbl. Salin per item elementer agar konversi terjadi. - Menggunakan COMP-1 atau COMP-2 untuk nilai uang. Keduanya adalah floating point yang tidak menyimpan pecahan desimal secara eksak, sehingga penjumlahan berulang menimbulkan selisih pembulatan. Gunakan COMP-3 atau COMP beserta simbol V untuk nilai uang.
- Membaca ulang berkas dengan definisi yang USAGE-nya berbeda dari saat ditulis. Byte yang tersimpan tidak berubah, tetapi pembacaannya kacau seperti pada salinan grup antar USAGE. Definisi record pada program penulis dan pembaca berkas harus identik.
Ringkasan#
- USAGE DISPLAY menyimpan satu digit per byte, simbol V tidak menambah byte, dan SIGN TRAILING SEPARATE menambah satu byte untuk tanda.
- COMP menyimpan biner dengan ukuran 2, 4, dan 8 byte untuk 1 sampai 4, 5 sampai 9, serta 10 sampai 18 digit, sedangkan COMP-3 menyimpan dua digit per byte ditambah nibel tanda.
- MOVE grup menyalin byte tanpa konversi, sehingga salinan antar USAGE menghasilkan data tak sah dan hanya MOVE elementer yang mengonversi dengan benar.
- Aritmetika tetap eksak pada ketiga USAGE, sedangkan pembedanya adalah ukuran berkas, keterbacaan, dan kecepatan pemrosesan.
Referensi#
- GnuCOBOL — Free Software Foundation — Situs proyek GnuCOBOL yang memuat rilis 3.2 tanggal 28 Juli 2023, versi yang dipakai sepanjang jalur ini.
- GnuCOBOL Manual — Free Software Foundation — Dokumen manual GnuCOBOL yang memuat klausa USAGE serta tabel ukuran penyimpanan COMP dan COMP-3.
- IBM Enterprise COBOL for z/OS documentation — IBM — Dokumentasi resmi yang memuat halaman USAGE clause beserta tabel byte biner dan desimal paket.