Deskripsi masalah
Saat menggunakan Java untuk menghitung angka titik mengambang dalam proyek, ditemukan bahwa untuk perhitungan seperti 4.015*100, hasilnya bukan 401.5 yang diharapkan, tetapi 401.49999999999999999999999999999994. Sejumlah besar digit tidak ramah untuk ditampilkan.
Penyebab Masalah: Representasi Angka Titik Mengambang
Setelah berkonsultasi dengan informasi yang relevan, saya menemukan bahwa alasannya adalah bahwa nomor titik mengambang di komputer tidak dapat sepenuhnya diekspresikan secara akurat. Misalnya, untuk tipe ganda 38414.4, komputer menyimpannya seperti ini:
Konversi ke biner: 1001011001110.01100110011001100110011001100110011001100
Berubah menjadi subjek
Pelajari Metode Penghitungan: 1.001011001111001100110011001100110011001100110011001100110011001100 × 2^15
Format pengkodean ganda adalah sebagai berikut:
tanda ganda bit 1 digit kode tahap 11 digit mantissa 52 digit
Bit simbol: Angka positif adalah 0
Kode pesanan: 15 adalah angka positif, jadi bit tertinggi adalah 1, bit terendah adalah minus 1, yaitu 10000001110
Mantissue: Lepaskan 1 bit tertinggi, yaitu 001011001111001100110011001100110011001100110011001100
Gabungan, pengkodean akhir adalah: 0 1000001110 001011000011100110011001100110011001100110011001100110011001100
Dari sini, kita dapat melihat bahwa alasan utamanya adalah bahwa encoding biner membuat bagian fraksional tidak mungkin untuk sepenuhnya mengekspresikan dengan tepat, seperti 0,4 = 0,25 + 0,125 + ..., yang hanya bisa sangat dekat. Oleh karena itu, kesalahan akurasi akan terjadi saat menghitung angka titik mengambang.
Solusi: Presisi tinggi
BigDecimal di Java dapat mendukung operasi angka floating point dengan presisi sewenang -wenang. Dalam buku "Efektif Java", disarankan agar float dan double digunakan untuk perhitungan ilmiah atau perhitungan rekayasa, sedangkan java.math.bigdecimal digunakan dalam perhitungan komersial.
Ada banyak metode konstruksi untuk BigDecimal, seperti BigDecimal (Double) dan BigDecimal (String). Perlu dicatat bahwa parameter konstruksi adalah tipe string untuk memastikan bahwa akurasi tidak hilang, karena tipe ganda itu sendiri tidak sepenuhnya akurat. Oleh karena itu, perlu ditulis sebagai berikut: BigDecimal ("0,02").
Operasi dasar tipe ganda dapat ditemukan di BigDecimal. Selain itu, BigDecimal juga dapat digunakan untuk memformat output dengan NumberFormat.
BigDecimal akan menghasilkan objek BigDecimal baru saat melakukan operasi, sehingga akan membawa lebih banyak overhead kinerja dibandingkan dengan ganda.
Studi pendahuluan tentang implementasi presisi tinggi
Jadi bagaimana BigDecimal dapat mewakili ketepatan sewenang -wenang? Ini hanya analisis pendahuluan.
Pertama, mari kita lihat implementasi BigInteger. Jenis int biasa adalah 32 bit, jadi ada batasan jangkauan. BigInteger memiliki variabel anggota int [] mag, sehingga semakin lama array int memungkinkan untuk mewakili bilangan bulat dalam ukuran apa pun.
Mari kita lihat implementasi BigDecimal. Pendahuluan resminya mengatakan bahwa setiap orang besar dapat direpresentasikan sebagai skala unscaledvalue × 10^-spale. UnscaledValue adalah integer dari ukuran apa pun, sesuai dengan variabel anggota Biginteger Intval dalam kode sumber; Skala adalah urutan, sesuai dengan skala int variabel dalam kode sumber. Dengan cara ini, BigDecimal diimplementasikan berdasarkan BigInteger.
Di atas adalah solusi untuk masalah akurasi titik mengambang di Java yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan.