Cetak 0.1 + 0.2 di sebagian besar bahasa pemrograman dan Anda akan mendapat 0.30000000000000004. Tidak ada yang rusak; beginilah cara komputer menyimpan bilangan real. Panduan ini menjelaskan format presisi ganda IEEE 754 yang dipakai SciKey dan sebagian besar perangkat lunak numerik, bagaimana keterbatasannya muncul dalam hasil, dan bagaimana kalkulator menanganinya.
1. Presisi ganda IEEE 754
Sebuah double (binary64) memakai 64 bit.
| Bagian | Bit | Peran |
|---|---|---|
| Tanda | 1 | Positif atau negatif |
| Eksponen | 11 | Pangkat 2 yang dipakai |
| Pecahan (mantissa) | 52 | Digit signifikan (efektifnya 53, dengan angka 1 terdepan yang tersembunyi) |
53 bit signifikan setara dengan sekitar 15 hingga 17 digit desimal. Nilai terbesar yang dapat direpresentasikan sekitar 1.797×10³⁰⁸, dan selisih antara 1 dan double berikutnya (epsilon mesin) adalah 2⁻⁵² ≈ 2.22×10⁻¹⁶.
2. 0.1 tidak memiliki bentuk biner yang eksak
Sama seperti 1/3 = 0.333… yang tidak pernah berakhir dalam desimal, 1/10 tidak pernah berakhir dalam biner: 0.1 = 0.0001100110011…₂ berulang tanpa henti. Nilainya dibulatkan ke 53 bit, sehingga yang tersimpan sebenarnya adalah
0.1000000000000000055511151231257827…
0.2 juga tersimpan sedikit lebih besar. Jumlah keduanya membawa kedua galat itu menjadi 0.3000000000000000444…, yang merupakan double yang berbeda dari double yang menyimpan 0.3 (0.2999999999999999888…). Desimal terpendek yang mengidentifikasi jumlah tersebut adalah 0.30000000000000004.
Dengan alasan yang sama, 0.1×3 juga bernilai 0.30000000000000004. Desimal yang penyebutnya pangkat dua, seperti 0.5, 0.25, dan 0.375, eksak dalam biner dan tidak membawa galat.
3. Mengapa kalkulator tetap menampilkan 0.3
SciKey tidak menampilkan nilai internal mentah; ia membulatkan sesuai pengaturan angka penting Anda (bawaan 12). Dibulatkan ke 12 digit, 0.30000000000000004 menjadi 0.300000000000, yaitu 0.3. Galatnya berada di digit ke-17 dan tidak pernah sampai ke layar.
Kalkulator ilmiah genggam bekerja dengan cara yang sama: biasanya menghitung dengan sekitar 15 digit internal dan menampilkan 10, sehingga galat kecil di digit belakang tersembunyi pada tahap tampilan. Hanya tampilannya yang berubah, jadi nilai tersimpannya tetap 0.30000000000000004. Jika dipakai dalam perhitungan lanjutan, biasanya galatnya tetap di sekitar 10⁻¹⁶, yang tidak berarti dalam praktik.
4. Mengapa sin(π) tidak nol
Dalam mode RAD, sin(π) seharusnya tepat 0. Namun π adalah bilangan irasional, dan double yang paling dekat dengan π sekitar 1.22×10⁻¹⁶ lebih kecil daripada nilai sebenarnya. Di sekitar π, sinus memiliki kemiringan −1, sehingga sin(π versi double) ≈ 1.2246×10⁻¹⁶. Sinusnya sendiri dihitung dengan akurat; masukannya memang tidak pernah tepat π.
SciKey mengoreksi hal ini dengan aturan berikut:
- Dalam mode DEG dan GRAD, argumen direduksi secara eksak dengan 360° (400 gon), dan kelipatan 90° menghasilkan nilai eksak:
sin(180)= 0,cos(90)= 0, dantan(90)tidak terdefinisi sehingga menghasilkan kesalahan. - Dalam mode RAD, jika argumen cocok dengan kelipatan bulat π dalam galat relatif 10⁻¹³, sin menghasilkan 0; jika cocok dengan kelipatan ganjil π/2, cos menghasilkan 0 dan tan menghasilkan kesalahan.
Jadi sin(π) menampilkan 0 di SciKey. Koreksi ini hanya berlaku di sekitar kelipatan π dan tidak memengaruhi perhitungan lain.
5. Bilangan besar: faktorial dan overflow
Faktorial tumbuh sangat cepat. 170! ≈ 7.25741561531×10³⁰⁶ masih muat dalam double, tetapi 171! sekitar 1.24×10³⁰⁹, melampaui batas maksimum 1.797×10³⁰⁸. Karena itulah n! di SciKey menerima bilangan bulat 0 hingga 170 dan 171! menghasilkan kesalahan overflow.
Dalam praktik, faktorial besar biasanya muncul di dalam rasio. Kombinasi C(200, 3) adalah 200!/(3!·197!), tetapi nCr(200, 3) = 1313400 menghitungnya secara langsung tanpa nilai antara yang raksasa. Dalam probabilitas, mengambil logaritma lalu menjumlahkannya juga merupakan teknik yang umum.
6. Batas bilangan bulat: 2⁵³
Dengan 53 bit signifikan, setiap bilangan bulat hingga 2⁵³ = 9007199254740992 tersimpan eksak. Di atas itu, double melompati sebagian bilangan bulat. 2⁵³ + 1 tidak dapat direpresentasikan dan dibulatkan kembali ke 2⁵³, sehingga 2^53+1-2^53 menghasilkan 0, bukan 1: angka 1 yang ditambahkan hilang saat jumlahnya disimpan.
Inilah sebabnya SciKey menampilkan biner, oktal, dan heksadesimal hanya untuk bilangan bulat dengan nilai mutlak hingga 2⁵³; di atas itu, digit-digit terendah tidak dijamin benar. Ini juga sebabnya nomor kartu atau ID yang lebih dari 16 digit berubah digit terakhirnya saat diperlakukan sebagai angka.
7. Pembatalan katastrofik: galat paling berbahaya
Mengurangkan dua bilangan yang hampir sama akan menghapus digit-digit depan dan menyisakan sebagian besar galat. Ini disebut pembatalan katastrofik (catastrophic cancellation).
Contoh 1. (1+1E-15)-1 seharusnya 10⁻¹⁵, tetapi presisi ganda memberi 1.11022302463×10⁻¹⁵. Menyimpan 1 + 10⁻¹⁵ menimbulkan galat pembulatan berorde 10⁻¹⁶, dan setelah dikurangi 1, galat itu menjadi 11% dari hasilnya.
Contoh 2. Untuk x = 10⁸, √(x²+1) − x kira-kira 5×10⁻⁹. Jika dihitung langsung, √(10¹⁶+1) tidak dapat dibedakan dari 10⁸ dan hasilnya 0. Merasionalkan memberi bentuk setara tanpa pengurangan:
√(x²+1) − x = 1 / (√(x²+1) + x)
Simpan 10⁸ di x dan 1/(sqrt(x^2+1)+x) menghasilkan 5×10⁻⁹ dengan akurat.
Contoh 3. 1 − cos(10⁻⁸) kira-kira 5×10⁻¹⁷, tetapi cos(10⁻⁸) dibulatkan menjadi tepat 1 dan hasil langsungnya 0. Dengan identitas 1 − cos x = 2 sin²(x/2), 2sin(0.5E-8)^2 menghasilkan 5×10⁻¹⁷ (mode RAD).
Berapa pun digit tampilan tidak akan memperbaiki masalah ini. Anda harus menulis ulang rumusnya.
8. Kiat praktis
- Jangan menguji kesamaan secara persis. Untuk membandingkan dua hasil perhitungan, periksa apakah selisihnya cukup kecil (misalnya galat relatif 10⁻¹²).
- Tangani uang dalam satuan utuh. Hitung dalam satuan mata uang terkecil sebagai bilangan bulat agar galat pecahan tidak menumpuk.
- Hindari mengurangkan bilangan yang hampir sama. Rasionalkan, gunakan identitas, atau susun ulang rumus untuk menghilangkan pengurangan.
- Gunakan rasio untuk bilangan besar. Jika faktorial atau pangkat membengkak, gunakan nCr, logaritma, atau coret suku-sukunya lebih dulu.
- Jangan membulatkan hasil antara. Galat presisi ganda sekitar 10⁻¹⁶, tetapi membulatkan secara manual ke empat digit menimbulkan galat sekitar 10⁻⁴. Galat yang lebih besar biasanya berasal dari manusia, bukan mesin.
- Coba naikkan tampilan menjadi 15 digit. Jika hasilnya tampak janggal, tampilkan lebih banyak digit untuk melihat nilai internal dan membedakan galat digit belakang dari rumus yang memang salah.