Topik ini membahas sistem bilangan pada Julia, yaitu tipe integer dan Float64 beserta hierarkinya, kemudian bilangan rasional Rational dan bilangan kompleks Complex. Pembahasan mencakup rentang tipe, perilaku overflow, pembagian biasa dan pembagian bulat, serta aritmetika pada pecahan dan bilangan kompleks. Setelah membacanya, tipe bilangan yang sesuai untuk sebuah perhitungan dapat dipilih dengan memahami konsekuensinya.
Integer dan tipe Int64#
Literal bilangan bulat tanpa titik desimal pada Julia menjadi Int64, yaitu integer berukuran 64 bit yang menampung nilai negatif dan positif. Batas bawah dan atasnya dapat dibaca dengan fungsi typemin() dan typemax().
umur = 17
println(typeof(umur))
println(typemin(Int64))
println(typemax(Int64))Int64
-9223372036854775808
9223372036854775807Rentang tersebut berlaku untuk seluruh perhitungan yang bertipe Int64. Apabila hasil operasi melampaui batas atasnya, Julia tidak menaikkan tipe secara otomatis dan tidak menampilkan error. Hasilnya justru bergulir ke sisi berlawanan, sebuah perilaku yang disebut overflow.
println(typemax(Int64) + 1)-9223372036854775808Menambahkan satu pada nilai terbesar menghasilkan nilai terkecil, dan tidak ada peringatan yang muncul. Perhitungan yang berpotensi melewati rentang perlu dirancang dengan sadar, misalnya dengan menggunakan BigInt untuk integer berukuran tak terbatas.
Float64 dan presisi biner#
Literal desimal seperti 0.1 menjadi Float64, yaitu bilangan pecahan IEEE 754 berukuran 64 bit. Karena Float64 menyimpan nilai dalam basis dua, banyak desimal yang tampak sederhana tidak dapat diwakili secara persis, dan hasilnya mengalami pembulatan (rounding) pada bit terakhir.
println(0.1 + 0.2)
println(0.1 + 0.2 == 0.3)
println(isapprox(0.1 + 0.2, 0.3))0.30000000000000004
false
trueJumlah 0.1 + 0.2 tercetak sebagai 0.30000000000000004, sedikit melenceng dari 0.3. Perbandingan == yang ketat bernilai false, sedangkan fungsi isapprox() yang membandingkan dengan toleransi bernilai true. Perilaku ini bukan kekhasan Julia, melainkan konsekuensi aritmetika pecahan basis dua yang diikuti hampir semua bahasa modern. Perbandingan hasil float sebaiknya menggunakan isapprox() atau batas toleransi yang dinyatakan eksplisit.
Pembagian biasa, pembagian bulat, dan sisa#
Operator / selalu menghasilkan Float64, bahkan ketika kedua operandnya integer dan hasilnya bulat sempurna. Untuk pembagian bulat, Julia menyediakan operator ÷ beserta fungsi div(), sedangkan sisa pembagian diperoleh dari rem().
println(4 / 2)
println(typeof(4 / 2))
println(7 ÷ 2)
println(div(7, 2))
println(rem(7, 2))
println(1 / 0)
try
println(div(1, 0))
catch err
println(typeof(err))
end2.0
Float64
3
3
1
Inf
DivideErrorPembagian 4 / 2 menghasilkan 2.0 bertipe Float64, sedangkan 7 ÷ 2 menghasilkan 3 bertipe integer karena bagian pecahannya dipotong. Pembagian 1 / 0 tidak memicu error dan menghasilkan Inf, yaitu nilai khusus untuk tak hingga. Sebaliknya, div(1, 0) memicu DivideError karena pembagian bulat dengan nol tidak memiliki hasil yang terdefinisi. Pemilihannya menyesuaikan kebutuhan, yaitu pembagian biasa menggunakan / dan pembagian bulat menggunakan ÷ atau div().
Hierarki tipe bilangan#
Seluruh tipe bilangan pada Julia berada di bawah tipe abstrak Number. Cabang Real menampung bilangan riil dan membaginya menjadi Integer, Rational, dan AbstractFloat, sedangkan cabang lain menampung bilangan kompleks. Di bawah Integer terdapat Signed untuk integer bertanda dan Unsigned untuk integer tanpa tanda. Diagram berikut memperlihatkan susunannya, dengan kotak biru untuk tipe abstrak dan kotak kuning untuk tipe konkret yang digunakan sehari-hari.
Posisi sebuah tipe dalam hierarki dapat dilacak dengan fungsi supertype(). Rantai berikut menaiki hierarki dari Int64 hingga Any, yaitu akar seluruh tipe Julia.
println(supertype(Int64))
println(supertype(Signed))
println(supertype(Integer))
println(supertype(Real))
println(supertype(Number))Signed
Integer
Real
Number
AnyRantai untuk Float64 menyusuri cabang yang berbeda, yaitu AbstractFloat, Real, Number, lalu Any. Keduanya bertemu kembali di Real, dan perbedaannya hanyalah cabang tengahnya. Hierarki inilah yang diacu ketika sebuah fungsi menerima argumen bertipe abstrak seperti Real, sehingga baik Int64 maupun Float64 diterima.
Bilangan rasional Rational#
Operator // membentuk bilangan rasional bertipe Rational{Int64}, yaitu pasangan pembilang dan penyebut integer. Julia menyederhanakan pecahan secara otomatis dengan faktor persekutuan terbesar, sehingga 6//8 langsung menjadi pecahan tiga per empat, .
r = 3//4
println(r)
println(typeof(r))
println(1//3 + 1//6)
println(numerator(r), "/", denominator(r))
println(float(r))3//4
Rational{Int64}
1//2
3/4
0.75Penjumlahan 1//3 + 1//6 menghasilkan 1//2 secara eksak tanpa pembulatan, sebagaimana dapat diperiksa pada persamaan berikut.
Fungsi numerator() dan denominator() mengambil pembilang serta penyebutnya, sedangkan float() mengonversinya ke Float64 beserta presisi binernya. Karena perhitungannya eksak, Rational cocok untuk perhitungan yang tidak boleh kehilangan ketelitian akibat pembulatan.
Sebagai contoh yang menyatukan materi rasional, berkas berikut menghitung rata-rata tiga nilai ujian dan menyimpannya sebagai bilangan rasional.
# Statistik sederhana: rata-rata tiga nilai ujian
a = 82
b = 90
c = 76
jumlah = a + b + c
rata_rata = jumlah // 3
println("Jumlah: ", jumlah)
println("Rata-rata (rasional): ", rata_rata)
println("Rata-rata (float): ", float(rata_rata))Jumlah: 248
Rata-rata (rasional): 248//3
Rata-rata (float): 82.66666666666667Rata-rata tidak dapat dinyatakan sebagai desimal berhingga, dan Rational menyimpannya persis sebagai 248//3. Konversi ke Float64 baru menghasilkan angka dengan pembulatan biner.
Bilangan kompleks Complex#
Akhiran im menyatakan satuan imajiner, sehingga 2 + 3im menjadi bilangan kompleks bertipe Complex{Int64}. Julia menyediakan aritmetika lengkap untuk tipe ini, termasuk penjumlahan, perkalian, konjugat dengan conj(), dan nilai mutlak dengan abs().
z = 2 + 3im
println(z)
println(typeof(z))
println(z * conj(z))
println(abs(3 + 4im))
println(real(z), " dan ", imag(z))2 + 3im
Complex{Int64}
13 + 0im
5.0
2 dan 3Perkalian z dengan konjugatnya menghasilkan 13 + 0im, yaitu jumlah kuadrat bagian riil dan imajinernya.
Fungsi abs() menghitung panjang vektor bilangan kompleks pada bidang, sehingga abs(3 + 4im) bernilai 5.0. Fungsi real() dan imag() mengambil bagian riil serta imajinernya. Tipe hasil aritmetika kompleks mengikuti tipe bagiannya, dan operasi yang melibatkan Float64 menghasilkan Complex{Float64}.
Kesalahan umum#
Kesalahan pertama adalah membandingkan hasil float dengan ==. Karena presisi biner Float64, jumlah 0.1 + 0.2 tidak sama persis dengan 0.3 dan perbandingannya bernilai false. Perbaikannya menggunakan isapprox() yang membandingkan dengan toleransi, sebagaimana ditunjukkan pada bagian presisi biner.
Kesalahan kedua adalah mengira operator / menghasilkan integer. Hasilnya selalu Float64, sehingga kode yang menuntut tipe integer perlu beralih ke ÷ atau div(). Kebalikannya juga perlu diwaspadai, yaitu mengira div(1, 0) menghasilkan Inf, padahal pembagian bulat dengan nol memicu DivideError.
Kesalahan ketiga adalah membaca hasil integer di dekat typemax(Int64) tanpa menyadari overflow. Perkalian yang terus berlipat, misalnya pada perhitungan faktorial, melampaui rentang Int64 dengan cepat, dan hasilnya bergulir tanpa peringatan. Gunakan BigInt apabila nilai yang dihitung dapat tumbuh melewati rentang tersebut.
Ringkasan#
- Literal integer menjadi
Int64dengan rentangtypemin()sampaitypemax(), dan hasil di luar rentang bergulir tanpa error. - Literal desimal menjadi
Float64yang mengikuti aritmetika biner, sehingga perbandingan float menggunakanisapprox(). - Operator
/selalu menghasilkanFloat64, sedangkan÷ataudiv()danrem()menangani pembagian bulat beserta sisanya. - Operator
//membentukRational{Int64}yang dihitung eksak, dan akhiranimmembentukComplex{Int64}beserta aritmetikanya.
Referensi#
- Integers and Floating-Point Numbers — The Julia Language — Rentang tipe integer, perilaku overflow, dan presisi Float64.
- Mathematical Operations and Elementary Functions — The Julia Language — Operator aritmetika, pembagian bulat, dan prioritas operasinya.
- Numbers — The Julia Language — Operasi pustaka standar untuk bilangan rasional dan kompleks.