|
|
Diposting pada 07/04/2015 14.53.05
|
|
|

Kelas operasi untuk bilangan besar disediakan di java, yaitu kelas java.math.BinInteger dan kelas java.math.BigDecimal. Kedua kelas ini digunakan untuk komputasi presisi tinggi, dengan kelas BigInteger menjadi kelas pemrosesan untuk bilangan bulat besar dan kelas BigDecimal menjadi kelas pemrosesan untuk bilangan besar dan kecil. Di bawah ini kami memperkenalkan kelas BigDecimal: Implementasi BigDecimal memanfaatkan BigInteger, kecuali BigDecimal menambahkan konsep desimal. Data tipe float dan ganda umum hanya dapat digunakan untuk perhitungan ilmiah atau perhitungan teknik, karena dalam komputasi komersial, akurasi numerik yang diperlukan relatif tinggi, sehingga kelas java.math.BigDecimal digunakan, yang mendukung presisi titik tetap, dan dapat digunakan untuk menghitung nilai mata uang secara akurat. Di bawah ini kami akan memperkenalkan penggunaannya secara singkat dengan contoh
java.math.BigDecimal
Hari ini, saya menulis program tentang konversi biner dan desimal dengan mengacu pada buku teks, dan algoritma programnya tidak sulit, tetapi setelah menulis, saya menemukan bahwa apakah itu 2 hingga 10 atau 10 banding 2, itu bukan konversi yang baik untuk angka yang lebih besar dari 2,1 miliar, yaitu lebih dari rentang bilangan bulat. akan menjadi 0. Buku referensi telah menemukan bahwa menggunakan BigInteger memecahkan masalah ini. Jadi saya mencari JDK, dan kemudian mengujinya beberapa kali dan akhirnya berhasil menulisnya! Pengalaman penggunaannya adalah sebagai berikut:
1. BigInteger milik java.math.BigInteger, jadi impor kelas ini sebelum digunakan. Kadang-kadang, saya lupa mengimpor di awal, sehingga prompt tidak dapat ditemukan di prompt konstan.
2. Ada banyak metode konstruksi, tetapi sekarang kadang-kadang digunakan: BigInteger(String val) Konversi representasi string desimal BigInteger ke BigInteger. BigInteger(String val, int radix) Mengonversi representasi string BigInteger untuk kardinalitas yang ditentukan menjadi BigInteger. Untuk mengonversi 2 jenis int ke jenis BigInteger, tulis BigInteger two=new BigInteger("2"); Catatan 2 tanda kutip ganda tidak dapat dihilangkan
3. Kelas BigInteger mensimulasikan semua operasi matematika tipe int, seperti add()=="+", divide()=="-", dll., tetapi perhatikan bahwa isinya tidak dapat digunakan secara langsung untuk operasi matematika saat melakukan operasi matematika, dan harus menggunakan metode internalnya. Dan operandnya juga harus bertipe BigInteger. Misalnya: two.add(2) adalah operasi yang salah karena 2 tidak menjadi jenis BigInteger.
4. Saat Anda ingin mengeluarkan hasil perhitungan, Anda harus menggunakan metode .toString untuk mengubahnya menjadi string desimal, seperti yang dijelaskan sebagai berikut: String keString() Mengembalikan representasi string desimal dari BigInteger ini. Metode keluaran: System.out.print(two.toString());
5. Jelaskan tiga fungsi yang digunakan. BigInteger remainder(BigInteger val) Mengembalikan BigInteger dengan nilai (% val ini). BigInteger negate() BigInteger mengembalikan nilai (-this). int compareTo(BigInteger val) Bandingkan BigInteger ini dengan BigInteger yang ditentukan. sisanya digunakan untuk menemukan sisanya. negate mengubah operan menjadi sebaliknya. Bandingkan dijelaskan secara rinci sebagai berikut: membandingkanKe
public int compareTo(BigInteger val)
Bandingkan BigInteger ini dengan BigInteger yang ditentukan. Metode ini lebih disukai untuk masing-masing dari enam operator perbandingan Boolean (<, ==, >, >=, !=, <=). Pernyataan yang disarankan untuk melakukan perbandingan ini adalah: (x.compareTo(y) <op> 0), di mana adalah <op> salah satu dari enam operator perbandingan.
Penentu: antarmuka<BigInteger> Sebanding
Parameter: val - BigInteger yang membandingkan BigInteger ini dengannya. Kembali:
Judul: Menerapkan Perhitungan Tepat Angka Floating Point di Jawa Modifikasi AYellow (Asli) Kata kunci Perhitungan tepat angka floating-point Java
Pertanyaan diajukan: Apa yang akan kita lihat jika kita mengkompilasi dan menjalankan program berikut? kelas publik Test{ public static void main(String args[]){ Sistem.keluar.println(0.05+0.01); Sistem.keluar.println(1.0-0.42); Sistem.keluar.println(4.015*100); Sistem.keluar.println(123.3/100); } };
Anda membacanya dengan benar! Hasilnya, memang 0.060000000000000005 0.5800000000000001 401.49999999999994 1.2329999999999999
Tipe float dan ganda sederhana di Java tidak dapat dioperasikan. Masalah ini tidak hanya ditemukan di Java, tetapi juga di banyak bahasa pemrograman lainnya. Dalam kebanyakan kasus, perhitungannya akurat, tetapi Anda dapat mencoba beberapa kali lagi (Anda dapat melakukan perulangan) untuk mencoba kesalahan seperti di atas. Sekarang saya akhirnya mengerti mengapa ada kode BCD. Masalah ini cukup serius, jika Anda memiliki 9,9999999999999999999999999 yuan, komputer Anda tidak akan berpikir bahwa Anda dapat membeli barang 10 yuan. Beberapa bahasa pemrograman menyediakan jenis mata uang khusus untuk menangani situasi ini, tetapi Java tidak. Sekarang mari kita lihat cara memperbaikinya.
Pembulatan Reaksi pertama kita adalah melakukan pembulatan. Metode bulat di kelas Matematika tidak dapat diatur untuk mempertahankan beberapa tempat desimal, kita hanya dapat melakukan ini (simpan dua tempat): putaran ganda publik(nilai ganda){ mengembalikan Math.round(value*100)/100.0; }
Sayangnya, kode di atas tidak berfungsi, meneruskan 4.015 ke metode ini akan mengembalikan 4.01, bukan 4.02, seperti yang kita lihat di atas 4.015*100=401.49999999999999994 Oleh karena itu, jika kita ingin melakukan pembulatan yang akurat, kita tidak dapat menggunakan jenis sederhana untuk melakukan operasi apa pun java.text.DecimalFormat juga tidak menyelesaikan masalah ini: System.out.println(java.text.DecimalFormat baru("0.00").format(4.025)); Outputnya adalah 4.02
Desimal Besar Prinsip ini juga disebutkan dalam buku "Jawa Efektif", float dan double hanya dapat digunakan untuk perhitungan ilmiah atau teknik, dan dalam komputasi bisnis kita perlu menggunakan java.math.BigDecimal. Ada 4 cara untuk membangun BigDecimal, kami tidak peduli dengan dua yang dibuat dengan BigInteger, jadi ada dua lagi, yaitu: BigDecimal(val ganda) Menerjemahkan ganda menjadi BigDecimal. BigDecimal(String val) Menerjemahkan representasi String dari BigDecimal menjadi BigDecimal.
API dijelaskan secara singkat dan biasanya lebih mudah digunakan. Kita mungkin menggunakannya tanpa memikirkannya, apa masalahnya? Ketika terjadi kesalahan, saya menemukan bahwa ada paragraf seperti itu dalam deskripsi terperinci tentang metode mana di atas yang cukup: Catatan: hasil konstruktor ini bisa agak tidak dapat diprediksi. Orang mungkin berasumsi bahwa BigDecimal(.1) baru persis sama dengan .1, tetapi sebenarnya sama dengan .1000000000000000055511151231257827021181583404541015625. Hal ini terjadi karena .1 tidak dapat direpresentasikan dengan tepat sebagai ganda (atau, dalam hal ini, sebagai pecahan biner dari panjang terbatas apa pun). Dengan demikian, nilai panjang yang diteruskan ke konstruktor tidak persis sama dengan .1, terlepas dari penampilan. Konstruktor (String), di sisi lain, dapat diprediksi dengan sempurna: BigDecimal(".1") baru persis sama dengan .1, seperti yang diharapkan. Oleh karena itu, umumnya disarankan agar konstruktor (String) digunakan lebih disukai daripada yang satu ini.
Ternyata jika kita perlu menghitung secara akurat, kita harus menggunakan String untuk membuat BigDecimal! Contoh dalam buku Java Efektif menggunakan String untuk membuat BigDecimal, tetapi buku tersebut tidak menekankan hal ini, yang mungkin merupakan kesalahan kecil.
Solusi Sekarang setelah kita memecahkan masalah ini, prinsipnya adalah menggunakan BigDecimal dan pastikan untuk menggunakan String. Tetapi bayangkan jika kita ingin melakukan operasi penjumlahan, pertama-tama kita perlu mengonversi dua angka floating-point menjadi String, lalu membuat BigDecimal, memanggil metode add pada salah satunya, meneruskan yang lain sebagai argumen, dan kemudian mengonversi hasil operasi (BigDecimal) menjadi angka floating-point. Bisakah Anda menanggung proses yang membosankan? Di bawah ini kami menyediakan kelas alat Aritik untuk menyederhanakan operasi. Ini menawarkan metode statis berikut, termasuk penjumlahan, pengurangan, perkalian dan pembagian, dan pembulatan: Publik Statis Double Add (Double V1, Double V2) sub ganda statis publik (double v1, double v2) Publik Statis Ganda Mul (Ganda V1, Ganda V2) Div ganda statis publik (double v1, double v2) Div Ganda Statis Publik (Double V1, Double V2, Int Scale) putaran ganda statis publik (double v, skala int)
Lampiran
File sumber Arith.java:
impor java.math.BigDecimal; /** * Karena jenis sederhana Java tidak dapat secara akurat melakukan operasi floating-point, kelas alat ini memberikan denda * Operasi floating-point yang tepat, termasuk penjumlahan, pengurangan, perkalian, pembagian, dan pembulatan. */
kelas publik Aritma{
Akurasi operasi pembagian default int akhir statis pribadi DEF_DIV_SCALE = 10;
Kelas ini tidak dapat dibuat-contoh pribadi Aritma(){ }
/** * Menyediakan operasi penambahan yang tepat. * @param v1 ditambahkan * Penambahan @param v2 * @return Jumlah dari dua parameter */
Publik Statis Ganda Tambahkan (Ganda V1, Ganda V2){ BigDecimal b1 = BigDecimal baru(Double.toString(v1)); BigDecimal b2 = BigDecimal baru(Double.toString(v2)); mengembalikan b1.add(b2).doubleValue(); }
/** * Menyediakan operasi pengurangan yang tepat. * @param v1 dikurangi * @param v2 minus * @return Perbedaan antara kedua parameter tersebut */
sub ganda statis publik(double v1, double v2){ BigDecimal b1 = BigDecimal baru(Double.toString(v1)); BigDecimal b2 = BigDecimal baru(Double.toString(v2)); mengembalikan b1.kurangi(b2).doubleValue(); }
/** * Menyediakan operasi perkalian yang tepat. * @param v1 dikalikan * Pengali @param v2 * @return Produk dari dua parameter */
Publik statis ganda mul (ganda v1, ganda v2){ BigDecimal b1 = BigDecimal baru(Double.toString(v1)); BigDecimal b2 = BigDecimal baru(Double.toString(v2)); mengembalikan b1.multiply(b2).doubleValue(); }
/** * Menyediakan operasi pembagian (relatif) akurat, ketika pembagian yang tidak ada habisnya terjadi * 10 tempat desimal dan digit berikut dibulatkan. * @param v1 dibagi * @param pembagi v2 * @return Hasil bagi dari dua parameter */
div ganda statis publik (double v1, double v2){ kembali div (v1,v2,DEF_DIV_SCALE); }
/** * Menyediakan operasi divisi (relatif) akurat. Ketika situasi yang tidak ada habisnya terjadi, itu ditunjukkan oleh parameter skala * Tentukan akurasi, dan angka setelahnya akan dibulatkan. * @param v1 dibagi * @param pembagi v2 * Skala @param menunjukkan bahwa itu harus akurat hingga beberapa tempat desimal. * @return Hasil bagi dari dua parameter */
Div ganda statis publik (double v1, double v2, skala int){ if(scale<0){ lempar IllegalArgumentException( baru "Skala harus berupa bilangan bulat positif atau nol"); } BigDecimal b1 = BigDecimal baru(Double.toString(v1)); BigDecimal b2 = BigDecimal baru(Double.toString(v2)); mengembalikan b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); }
/** * Memberikan pembulatan desimal yang tepat. * @param v memerlukan angka pembulatan * Skala @param dicadangkan setelah titik desimal * @return Hasil bulat */
putaran ganda statis publik (double v, skala int){ if(scale<0){ lempar IllegalArgumentException( baru "Skala harus berupa bilangan bulat positif atau nol"); } BigDecimal b = BigDecimal baru(Double.toString(v)); BigDecimal satu = BigDecimal baru("1"); mengembalikan b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } }; |
Mantan:Yang terbaik adalah tidak menetapkan string dengan makna sebagai kunci primerDepan:Perbedaan dan koneksi JDK, JRE, JVM
|