Tipe integer

Rentang nilai yang melekat pada tipe integer beserta luapan yang tertangkap sejak rancangan.

Daftar isi

Tipe integer pada Ada memuat rentang nilai sebagai bagian dari definisinya, bukan sebagai kesepakatan di luar bahasa. Topik ini membahas tipe Integer bawaan, cara mendefinisikan tipe dengan kendala range, dan pemeriksaan luapan yang menyertainya. Setelah membacanya, tipe bilangan bulat untuk sebuah pengukuran dapat didefinisikan dengan rentang yang tepat, dan kegagalan aritmetikanya tertangkap sejak waktu kompilasi maupun waktu berjalan.

Tipe Integer bawaan dan atribut rentang#

Tipe Integer adalah tipe bilangan bulat bawaan yang disediakan oleh setiap implementasi Ada. Rentang persisnya ditentukan oleh kompilator dan platform, sedangkan atribut First dan Last menyatakan rentang itu pada program. Atribut Size menyatakan jumlah bit yang digunakan untuk menyimpan satu nilai. Jalankan program berikut untuk membaca ketiganya pada lingkungan GNAT di jalur ini.

ada batas_integer.adb
with Ada.Text_IO;

procedure Batas_Integer is
begin
   Ada.Text_IO.Put_Line ("Integer'First = " & Integer'Image (Integer'First));
   Ada.Text_IO.Put_Line ("Integer'Last = " & Integer'Image (Integer'Last));
   Ada.Text_IO.Put_Line ("Ukuran bit = " & Integer'Image (Integer'Size));
end Batas_Integer;
bash
# kompilasi program
gnatmake -q batas_integer.adb
# jalankan program
./batas_integer
text Keluaran
Integer'First = -2147483648
Integer'Last =  2147483647
Ukuran bit =  32

Pada lingkungan ini, Integer menempati 32 bit dengan rentang dari -2147483648 hingga 2147483647. Perhatikan perilaku atribut Image pada tiga baris keluaran: bilangan negatif dicetak tanpa spasi di depan, sedangkan bilangan nonnegatif memperoleh satu spasi. Karena string pada program sudah memuat satu spasi setelah tanda sama dengan, baris kedua dan ketiga memuat dua spasi, sedangkan baris pertama hanya satu. Tuliskan batas tipe melalui atributnya dan jangan menyalin angka 2147483647 secara langsung, agar program tetap benar pada platform dengan rentang yang berbeda.

Mendefinisikan tipe dengan kendala range#

Sebuah tipe integer baru didefinisikan dengan kata type, nama tipe, dan kendala range. Definisi type Tegangan is range 0 .. 240; memperkenalkan tipe Tegangan yang hanya menerima nilai 0 hingga 240, dan tipe ini bukan alias untuk Integer melainkan tipe yang berdiri sendiri. Setiap tipe integer juga memiliki tipe dasar (base type) anonim yang rentangnya lebih luas daripada kendala yang dituliskan. Hasil operasi dihitung pada tipe dasar, kemudian kendala tipe diperiksa kembali ketika hasilnya disimpan ke variabel.

Program berikut mendeklarasikan Tegangan dan menampilkan atribut rentangnya beserta ukuran penyimpanannya.

ada rentang.adb
with Ada.Text_IO;

procedure Rentang is
   type Tegangan is range 0 .. 240;
   T : Tegangan := 230;
begin
   Ada.Text_IO.Put_Line (Tegangan'Image (T));
   Ada.Text_IO.Put_Line (Tegangan'Image (Tegangan'First));
   Ada.Text_IO.Put_Line (Tegangan'Image (Tegangan'Last));
   Ada.Text_IO.Put_Line ("Ukuran bit = " & Tegangan'Size'Image);
end Rentang;
bash
# kompilasi program
gnatmake -q rentang.adb
# jalankan program
./rentang
text Keluaran
 230
 0
 240
Ukuran bit =  8

Atribut First dan Last mengikuti kendala yang dituliskan, yaitu 0 dan 240, sehingga pembaca program mengetahui rentang sahnya tanpa membuka dokumentasi lain. Atribut Size menunjukkan bahwa GNAT memilih penyimpanan 8 bit karena seluruh rentang muat dalam satu byte. Penyimpanan yang kecil ini diperoleh tanpa konfigurasi tambahan, cukup dari kendala rentang yang ditulis pada definisi tipe. Satu spasi di depan angka pada tiga baris pertama berasal dari perilaku atribut Image yang sudah dijelaskan pada bagian sebelumnya.

Luapan yang tertangkap sejak rancangan#

Operasi aritmetika pada tipe integer diperiksa pada setiap hasilnya, dan hasil yang keluar dari rentang melempar exception Constraint_Error. Pemeriksaan ini aktif secara bawaan tanpa switch tambahan, dan kompilator bahkan memberi peringatan apabila luapannya sudah pasti terbaca dari program. Program berikut menaikkan penghitung dari Integer'Last sebanyak satu langkah, sebuah operasi yang pasti melampaui rentang.

ada luapan.adb
with Ada.Text_IO;

procedure Luapan is
   Penghitung : Integer := Integer'Last;
begin
   Penghitung := Penghitung + 1;
   Ada.Text_IO.Put_Line ("tidak pernah dicapai");
end Luapan;
bash
# kompilasi lalu jalankan program yang meluap
gnatmake -q luapan.adb
./luapan
text Keluaran
luapan.adb:6:29: warning: value not in range of type "Standard.Integer" [enabled by default]
luapan.adb:6:29: warning: Constraint_Error will be raised at run time [enabled by default]

raised CONSTRAINT_ERROR : luapan.adb:6 overflow check failed

Dua baris pertama keluaran adalah peringatan waktu kompilasi: GNAT menyimpulkan dari nilai awal Penghitung bahwa hasil Penghitung + 1 berada di luar rentang Integer. Baris terakhir adalah pesan exception pada waktu berjalan (run time) yang menyebut berkas, baris, dan jenis pemeriksaannya, yaitu pemeriksaan luapan (overflow check). Program tidak pernah mencapai Put_Line karena eksekusi berhenti pada penugasan yang meluap. Pada bahasa yang melipat hasil luapan secara diam-diam, kesalahan semacam ini menyusup ke perhitungan berikutnya, sedangkan pada Ada program berhenti tepat pada titik kesalahannya.

Kesalahan umum#

Tiga kekeliruan berikut sering muncul saat tipe integer dirancang dan digunakan.

  • Mengasumsikan rentang Integer sama di semua platform. Rentangnya ditentukan implementasi, dan program yang menyalin angka batas secara langsung dapat menjadi salah pada platform lain. Gunakan atribut First, Last, dan Size agar batasnya selalu mengikuti lingkungan yang digunakan.
  • Mengharapkan hasil luapan melipat seperti pada beberapa bahasa lain. Dengan pemeriksaan bawaan, hasil yang keluar dari rentang melempar Constraint_Error dan bukan nilai yang melipat. Rancang rentang tipe agar setiap hasil perhitungan yang sah muat di dalamnya.
  • Mencampur dua tipe integer yang berbeda dalam satu operasi tanpa konversi. Kompilator menolaknya sebagai error tipe yang tidak cocok, dan konversi antar tipe yang berhubungan dibahas pada topik tentang subtype dan tipe turunan.

Ringkasan#

  • Rentang Integer bawaan ditentukan implementasi, dan atribut First, Last, serta Size menyatakannya pada program.
  • Tipe dengan kendala range membatasi himpunan nilai yang sah, dan kendalanya diperiksa kembali pada setiap penyimpanan hasil operasi.
  • Luapan melempar Constraint_Error secara bawaan, dan kompilator GNAT memberi peringatan apabila luapan itu sudah pasti dari program.

Referensi#