misalnya, dengan dolar, Anda tidak pernah memiliki ketepatan kurang dari $ 0,01
Oh benarkah?
masalah lama mengapa Anda tidak harus menyimpan mata uang sebagai nomor floating point IEEE 754.
Silakan menyimpan inci dalam nomor floating point IEEE 754 . Mereka menyimpan persis seperti yang Anda harapkan.
Jangan ragu untuk menyimpan sejumlah uang dalam nomor floating point IEEE 754 yang dapat Anda simpan menggunakan kutu yang membagi penggaris menjadi pecahan satu inci.
Mengapa? Karena ketika Anda menggunakan IEEE 754 itulah cara Anda menyimpannya.
Hal tentang inci adalah mereka dibagi menjadi dua. Hal tentang sebagian besar jenis mata uang adalah mereka dibagi dalam sepuluh (beberapa jenis tidak tetapi mari kita tetap fokus).
Perbedaan ini tidak akan terlalu membingungkan kecuali bahwa, untuk sebagian besar bahasa pemrograman, input dan output dari angka-angka floating point IEEE 754 dinyatakan dalam desimal! Yang sangat aneh karena mereka tidak disimpan dalam desimal.
Karena ini, Anda tidak pernah bisa melihat bagaimana bit melakukan hal-hal aneh ketika Anda meminta komputer untuk menyimpan 0.1
. Anda hanya melihat keanehan ketika Anda melakukan matematika melawannya dan itu memiliki kesalahan aneh.
Dari java efektif Josh Bloch :
System.out.println(1.03 - .42);
Menghasilkan 0.6100000000000001
Apa yang paling banyak diceritakan tentang ini bukanlah 1
cara duduk di sebelah kanan. Ini angka aneh yang harus digunakan untuk mendapatkannya. Daripada menggunakan contoh yang paling populer 0.1
, kita harus menggunakan contoh yang menunjukkan masalah dan menghindari pembulatan yang akan menyembunyikannya.
Misalnya, mengapa ini bekerja?
System.out.println(.01 - .02);
Menghasilkan -0.01
Karena kita beruntung.
Saya benci masalah yang sulit didiagnosis karena kadang-kadang saya "beruntung".
IEEE 754 tidak bisa menyimpan 0,1 dengan tepat. Tetapi jika Anda memintanya untuk menyimpan 0,1 dan kemudian meminta untuk mencetak maka itu akan menampilkan 0,1 dan Anda akan berpikir semuanya baik-baik saja. Ini tidak baik, tetapi Anda tidak dapat melihat itu karena pembulatan untuk kembali ke 0,1.
Beberapa orang mengacaukan heck out dari orang lain dengan menyebut perbedaan ini untuk memperbaiki kesalahan. Tidak, ini bukan kesalahan pembulatan. Pembulatan adalah melakukan apa yang seharusnya dan mengubah apa yang bukan desimal menjadi desimal sehingga dapat dicetak di layar.
Tapi ini menyembunyikan ketidakcocokan antara bagaimana nomor ditampilkan dan bagaimana disimpan. Kesalahan tidak terjadi ketika pembulatan terjadi. Itu terjadi ketika Anda memutuskan untuk memasukkan nomor ke dalam sistem yang tidak dapat menyimpannya dengan tepat dan menganggap itu disimpan tepat ketika tidak.
Tidak ada yang mengharapkan π untuk menyimpan secara tepat dalam kalkulator dan mereka berhasil bekerja dengan baik. Jadi masalahnya bukan tentang presisi. Ini tentang presisi yang diharapkan. Komputer menampilkan sepersepuluh 0.1
sama dengan kalkulator kami, jadi kami berharap mereka menyimpan sepersepuluh dengan sempurna seperti yang dilakukan kalkulator kami. Mereka tidak melakukannya. Yang mengejutkan, karena komputer lebih mahal.
Mari saya tunjukkan ketidakcocokan:
Perhatikan bahwa 1/2 dan 0,5 berbaris dengan sempurna. Tapi 0,1 tidak berbaris. Tentu Anda bisa lebih dekat jika Anda terus membaginya dengan 2 tetapi Anda tidak akan pernah memukulnya dengan tepat. Dan kita membutuhkan semakin banyak bit setiap kali kita bagi dengan 2. Jadi, mewakili 0,1 dengan sistem apa pun yang membaginya dengan 2 membutuhkan jumlah bit yang tak terbatas. Hard drive saya tidak sebesar itu.
Jadi IEEE 754 berhenti mencoba ketika kehabisan bit. Yang bagus karena saya perlu ruang di hard drive saya untuk ... foto keluarga. Tidak benar-benar. Foto keluarga. : P
Bagaimanapun, apa yang Anda ketikkan dan apa yang Anda lihat adalah desimal (di sebelah kanan) tetapi yang Anda simpan adalah bicimal (di sebelah kiri). Terkadang itu sama persis. Terkadang tidak. Terkadang sepertinya mereka sama, padahal sebenarnya tidak. Itulah pembulatannya.
Khususnya, apa yang perlu kita ketahui untuk dapat menyimpan nilai dalam beberapa mata uang dan mencetaknya?
Tolong, jika Anda menangani uang berbasis desimal saya, jangan gunakan pelampung atau ganda.
Jika Anda yakin hal-hal seperti sepersepuluh uang tidak akan terlibat maka simpan saja uang itu. Jika Anda tidak mencari tahu unit terkecil dari mata uang ini akan menjadi dan menggunakannya. Jika Anda tidak bisa, gunakan sesuatu seperti BigDecimal .
Kekayaan bersih saya mungkin akan selalu cocok dengan integer 64 bit, tetapi hal-hal seperti BigInteger bekerja dengan baik untuk proyek-proyek yang lebih besar dari itu. Mereka lebih lambat dari tipe asli.
Mencari tahu bagaimana menyimpannya hanya setengah dari masalah. Ingat Anda juga harus bisa menampilkannya. Desain yang baik akan memisahkan kedua hal ini. Masalah sebenarnya dengan menggunakan pelampung di sini adalah kedua hal itu disatukan.