Topik ini merinci tipe bilangan Erlang, mulai dari bilangan bulat presisi arbitrer, literal berbasis lain, aritmetika float, hingga operator logika dan aturan perbandingan antar tipe. Semua contoh dievaluasi nyata di shell OTP 29 sehingga setiap nilai, termasuk keluaran yang tampak aneh pada float, tertangkap apa adanya.
Bilangan bulat presisi arbitrer#
Bilangan bulat pada Erlang tidak memiliki batas ukuran yang menempel pada tipe mesin. Operasi boleh membesar tanpa risiko overflow karena VM mengelola memorinya sendiri. Perkalian berikut melampaui batas bilangan 64-bit, tetapi hasilnya tetap tepat:
Erlang/OTP 29 [erts-17.1.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]
Eshell V17.1.1 (press Ctrl+G to abort, type help(). for help)
1> 123456789 * 987654321.
121932631112635269Selain penulisan desimal, literal bilangan bulat mendukung basis lain dengan format Basis#Angka, serta literal karakter dengan awalan $. Ketiganya menghasilkan bilangan bulat biasa:
2> 2#1010.
10
3> 16#ff.
255
4> $A.
652#1010 adalah 10 dalam biner, 16#ff adalah 255 dalam heksadesimal, dan $A adalah kode karakter A sebesar 65. Bentuk-bentuk ini sering muncul saat bekerja dengan protokol biner dan penguraian teks pada topik penyimpanan dan binary.
Aritmetika float#
Bilangan float Erlang mengikuti standar double precision IEEE 754, sebagaimana umumnya bahasa modern. Operator pembagian / selalu menghasilkan float, sedangkan pembagian bilangan bulat dipakai lewat div dan sisa pembagiannya lewat rem:
5> 10 / 4.
2.5
6> 10 div 4.
2
7> 10 rem 4.
2
8> 10 / 2.
5.0Perhatikan baris terakhir: 10 / 2. menghasilkan 5.0, bukan 5, karena operator / memang selalu float. Kebalikannya, div dan rem hanya menerima bilangan bulat dan menghasilkan bilangan bulat, sehingga campurannya perlu dikonversi secara eksplisit.
Presisi float membawa konsekuensi yang sebaiknya dikenal sejak awal. Sebagian bilangan desimal tidak dapat direpresentasikan persis dalam biner, sehingga hasil penjumlahannya tampak janggal:
9> 0.1 + 0.2.
0.30000000000000004Keluaran 0.30000000000000004 bukan bug Erlang, melainkan konsekuensi representasi biner IEEE 754 yang sama dengan bahasa lain. Untuk perhitungan yang menuntut ketepatan desimal penuh, misalnya nilai uang, menyimpan kelipatan integer atau penanganan khusus lebih aman daripada float mentah.
Konversi dan pemeriksaan tipe#
Karena / selalu float dan div murni bilangan bulat, konversi antara keduanya disediakan lewat fungsi khusus. Fungsi trunc/1 memotong bagian desimal, round/1 membulatkan ke bilangan terdekat, dan float/1 mengubah bilangan bulat menjadi float. Pemeriksaan tipe memakai keluarga fungsi is_integer/1, is_float/1, dan is_number/1 yang mengembalikan nilai kebenaran:
1> trunc(5.9).
5
2> round(5.4).
5
3> float(5).
5.0
4> is_integer(10).
true
5> is_number(2.5).
trueis_number/1 menerima keduanya, sedangkan is_integer/1 menolak float. Pembanding =:= membedakan tipe secara ketat, sehingga 2.0 =:= 2. bernilai false meski nilainya setara. Perbandingan == yang lebih longgar justru menghasilkan true. Perbedaan ini penting diingat saat membandingkan hasil pembagian dengan bilangan bulat, dan fungsi is_* kelak menjadi bahan utama guard pada modul ini.
Fungsi bawaan bilangan dan pembagian nol#
Selain operator, beberapa fungsi bawaan bilangan dipakai setiap hari. Fungsi abs/1 menghitung nilai mutlak, min/2 dan max/2 memilih bilangan terkecil atau terbesar, dan modul math menyediakan fungsi matematis seperti akar kuadrat dengan hasil float:
1> math:sqrt(16).
4.0
2> abs(-7).
7
3> erlang:min(3, 9).
3
4> erlang:max(3, 9).
9Pembagian dengan nol tidak menghasilkan nilai khusus, melainkan error. Baik 10 / 0. maupun 1 div 0. memicu exception aritmetika dengan pesan yang menyebut operator dan operandnya:
5> 10 / 0.
** exception error: an error occurred when evaluating an arithmetic expression
in operator '/'/2
called as 10 / 0
6> 1 div 0.
** exception error: an error occurred when evaluating an arithmetic expression
in operator div/2
called as 1 div 0Perilaku ini konsisten dengan filosofi bahasa: kejadian yang tidak seharusnya terjadi dilaporkan segera, bukan ditoleransi dengan nilai semu seperti tak hingga. Pemanggil yang tahu pembaginya bisa nol memeriksa nilainya terlebih dahulu, misalnya dengan cabang case atau guard yang dibahas pada modul ini.
true dan false serta operator logika#
Nilai kebenaran Erlang hanya dua, yaitu atom true dan atom false. Operator logika terbagi menjadi dua kelompok. Kelompok andalso dan orelse mengevaluasi sisi kedua hanya bila diperlukan, sedangkan and dan or selalu mengevaluasi kedua sisi:
10> 5 > 3 andalso 2 < 4.
true
11> false andalso (1 / 0 =:= 0).
false
12> false and (1 / 0 =:= 0).
** exception error: an error occurred when evaluating an arithmetic expression
in operator '/'/2
called as 1 / 0Ekspresi ke-11 menghasilkan false tanpa mengeksekusi 1 / 0, karena andalso berhenti begitu sisi pertama pasti false. Ekspresi ke-12 dengan operator and tetap mengevaluasi pembagian nol dan memicu error badarith. Perbedaan ini praktis: gunakan andalso dan orelse bila sisi kedua mahal atau berisiko error, dan and dengan or bila kedua sisi harus dihitung. Negasi memakai not, dan xor tersedia untuk gabungan eksklusif.
Urutan tipe pada perbandingan#
Operator < dan > dapat membandingkan nilai dari tipe berbeda karena seluruh tipe Erlang punya urutan total yang ditetapkan bahasa. Urutannya dari yang terkecil: bilangan, atom, reference, fun, port, PID, tuple, map, list, dan bitstring. Hasil nyatanya seperti berikut:
4> 1 < merah.
true
5> merah < {1}.
true
6> {1, 2} < [1].
true
7> [1] < <<"x">>.
trueKeempat perbandingan bernilai true dan masing-masing menaikkan satu tingkat tipe: bilangan di bawah atom, atom di bawah tuple, tuple di bawah list, dan list di bawah bitstring. Urutan total inilah yang membuat fungsi pengurutan seperti lists:sort/1 tetap bekerja pada list campuran, meski secara praktik membandingkan tipe yang tidak lazim dibandingkan biasanya merupakan tanda desain yang perlu ditinjau.
Ringkasan#
- Bilangan bulat Erlang berpresisi arbitrer tanpa risiko overflow, dengan literal basis lain 2#1010 dan 16#ff serta literal karakter $A.
- Operator / selalu menghasilkan float, sedangkan div dan rem murni bilangan bulat.
- Float mengikuti IEEE 754 dan hasil semacam 0.1 + 0.2 = 0.30000000000000004 adalah konsekuensi representasinya.
andalsodanorelsemengevaluasi pendek, sedangkananddanorselalu mengevaluasi kedua sisi.- trunc, round, dan float mengonversi antara bilangan bulat dan float, sedangkan keluarga is_integer, is_float, dan is_number memeriksa tipe.
- Perbandingan lintas tipe mengikuti urutan total bahasa: bilangan, atom, reference, fun, port, PID, tuple, map, list, bitstring.
Referensi#
- Erlang Reference Manual: Data Types — Ericsson — Dokumentasi resmi tipe bilangan bulat, float, dan representasinya.
- Erlang Reference Manual: Expressions — Ericsson — Tabel operator aritmetika, logika, dan urutan tipe pada perbandingan.
- Learn You Some Erlang for Great Good! — Fred Hebert — Bab yang memperkenalkan aritmetika dan tipe dasar Erlang di shell.