Saya sedang menonton http://www.joelonsoftware.com/items/2011/06/27.html dan menertawakan lelucon Jon Skeet tentang 0,3 tidak menjadi 0,3. Saya pribadi tidak pernah memiliki masalah dengan float / desimal / ganda tetapi kemudian saya ingat saya belajar 6502 sangat awal dan tidak pernah membutuhkan float di sebagian besar program saya. Satu-satunya waktu saya menggunakannya untuk grafik dan matematika di mana angka-angka yang tidak akurat ok dan output untuk layar dan tidak untuk disimpan (dalam db, file) atau tergantung pada.
Pertanyaan saya adalah, di mana tempat-tempat yang biasanya Anda gunakan pelampung / desimal / ganda? Jadi saya tahu harus waspada terhadap gotcha ini. Dengan uang, saya menggunakan long dan menyimpan nilai per sen, untuk kecepatan suatu objek dalam permainan, saya menambahkan int dan membagi (atau bitshift) nilai untuk mengetahui apakah saya perlu memindahkan piksel atau tidak. (Saya membuat objek bergerak dalam 6502 hari, kami tidak memiliki celah atau mengapung tetapi memiliki pergeseran).
Jadi saya sebagian besar penasaran.
sumber
Jawaban:
Karena, untuk sebagian besar tujuan, lebih akurat daripada bilangan bulat.
Sekarang bagaimana itu? "untuk kecepatan objek dalam permainan ..." ini adalah contoh yang bagus untuk kasus seperti itu. Katakanlah Anda perlu memiliki beberapa objek yang sangat cepat, seperti peluru. Untuk dapat menggambarkan gerakan mereka dengan variabel kecepatan integer, Anda harus memastikan kecepatannya berada dalam kisaran variabel integer, itu berarti Anda tidak dapat memiliki raster yang berubah-ubah.
Tapi kemudian, Anda mungkin juga ingin menggambarkan beberapa objek yang sangat lambat, seperti jarum jam. Karena ini sekitar 6 urutan besarnya lebih lambat dari objek peluru, ld pertama (10⁶) bits 20 bit adalah nol, yang mengesampingkan
short int
jenis dari awal. Ok, hari ini kita punyalong
di mana-mana, yang meninggalkan kita dengan 12 bit yang masih nyaman. Tetapi meskipun demikian, kecepatan jam akan tepat hanya untuk empat tempat desimal. Itu bukan jam yang sangat bagus ... tapi tentu saja ok untuk sebuah game. Hanya saja, Anda tidak ingin membuat raster lebih kasar dari yang sudah ada.... yang mengarah ke masalah jika suatu hari Anda ingin memperkenalkan jenis objek baru yang lebih cepat. Tidak ada "ruang kepala" yang tersisa.
Apa yang terjadi jika kita memilih tipe float? Ukuran yang sama dari 32 bit, tetapi sekarang Anda memiliki presisi 24 bit penuh, untuk semua objek. Itu berarti, jam memiliki presisi yang cukup untuk tetap sinkron hingga detik selama bertahun-tahun. Peluru tidak memiliki presisi yang lebih tinggi, tetapi mereka hanya "hidup" untuk sepersekian detik, jadi itu akan sama sekali tidak berguna jika mereka punya. Dan Anda tidak mendapatkan masalah apa pun jika Anda ingin menggambarkan objek yang jauh lebih cepat (mengapa tidak kecepatan cahaya? Tidak masalah) atau yang jauh lebih lambat. Anda tentu tidak akan membutuhkan hal-hal seperti itu dalam permainan, tetapi kadang-kadang Anda lakukan dalam simulasi fisika.
Dan dengan angka floating-point, Anda mendapatkan ketepatan yang sama ini selalu dan tanpa terlebih dahulu harus pintar memilih beberapa raster yang tidak jelas. Itu mungkin poin yang paling penting, karena kebutuhan pilihan seperti itu sangat rawan kesalahan.
sumber
Anda menggunakannya ketika Anda menggambarkan nilai kontinu daripada nilai diskrit . Tidak ada yang lebih rumit untuk dijelaskan daripada itu. Hanya saja, jangan membuat kesalahan dengan mengasumsikan nilai dengan titik desimal adalah kontinu. Jika itu berubah sekaligus dalam potongan, seperti menambahkan satu sen, itu terpisah.
sumber
Anda benar-benar memiliki dua pertanyaan di sini.
Kenapa sih ada yang butuh matematika floating point?
Seperti yang ditunjukkan Karl Bielefeldt, angka floating point memungkinkan Anda memodelkan jumlah terus menerus - dan Anda menemukan semuanya di mana-mana - tidak hanya di dunia fisik, tetapi bahkan tempat-tempat seperti bisnis dan keuangan.
Saya telah menggunakan matematika floating point dalam banyak, banyak bidang dalam karir pemrograman saya: kimia, bekerja di AutoCAD, dan bahkan menulis simulator Monte Carlo untuk melakukan prediksi keuangan. Bahkan, ada seorang pria bernama David E. Shaw yang menggunakan teknik pemodelan ilmiah berbasis floating-point untuk Wall Street untuk menghasilkan miliaran.
Dan, tentu saja, ada grafik komputer. Saya berkonsultasi untuk mengembangkan eye candy untuk antarmuka pengguna, dan mencoba melakukannya saat ini tanpa pemahaman yang kuat tentang floating point, trigonometri, kalkulus, dan aljabar linier, akan seperti muncul untuk pertarungan senjata dengan pisau lipat.
Mengapa ada yang butuh pelampung versus ganda ?
Dengan representasi standar IEEE 754, float 32-bit memberi Anda sekitar 7 digit desimal akurasi, dan eksponen dalam kisaran 10 -38 hingga 10 38 . Double 64-bit memberi Anda sekitar 15 digit desimal akurasi, dan eksponen dalam kisaran 10 -307 hingga 10 307 .
Ini mungkin tampak seperti pelampung yang cukup untuk apa yang dibutuhkan oleh siapa pun, tetapi ternyata tidak. Misalnya, banyak kuantitas dunia nyata diukur dalam lebih dari 7 digit desimal.
Tapi yang lebih halus, ada masalah bahasa sehari-hari yang disebut "kesalahan pembulatan". Representasi titik mengambang biner hanya berlaku untuk nilai yang bagian pecahannya memiliki penyebut yang memiliki kekuatan 2, seperti 1/2, 1/4, 3/4, dll. Untuk mewakili fraksi lain, seperti 1/10, Anda "bulat" nilai ke fraksi biner terdekat, tapi itu sedikit salah - itulah "kesalahan pembulatan". Kemudian ketika Anda menghitung dengan angka-angka yang tidak akurat itu, ketidakakuratan dalam hasil bisa jauh lebih buruk daripada yang Anda mulai - kadang-kadang persentase kesalahan berlipat ganda, atau bahkan menumpuk secara eksponensial.
Bagaimanapun, semakin banyak digit biner yang harus Anda kerjakan, semakin dekat representasi biner bulat Anda akan ke angka yang Anda coba wakili, sehingga kesalahan pembulatannya akan lebih kecil. Kemudian ketika Anda melakukan perhitungan matematika, jika Anda memiliki banyak digit untuk dikerjakan, Anda dapat melakukan lebih banyak operasi sebelum kesalahan pembulatan kumulatif menumpuk di mana itu merupakan masalah.
Sebenarnya, 64-bit ganda dengan 15 angka desimal mereka tidak cukup baik untuk banyak aplikasi. Saya menggunakan angka floating point 80-bit pada tahun 1985, dan IEEE sekarang mendefinisikan tipe floating point 128-bit (16-byte), yang dapat saya bayangkan digunakan.
sumber
Ini adalah kesalahpahaman umum, bahwa di mana pun Anda berurusan dengan uang, Anda harus menyimpan nilainya sebagai bilangan bulat (sen). Walaupun dalam beberapa kasus sederhana seperti toko online itu benar, jika Anda memiliki sesuatu yang lebih canggih, itu tidak banyak membantu.
Mari kita ambil contoh: seorang pengembang menghasilkan $ 100.000 setahun. Berapa gaji bulannya? Menggunakan integer Anda mendapatkan hasil $ 8333,33 (¢ 833333), yang dikalikan dengan 12 adalah $ 99.999,96. Apakah menjaganya sebagai integer membantu? Tidak, tidak.
Apakah bank selalu menggunakan nilai desimal / integer? Ya, mereka melakukannya untuk bagian transaksional. Tapi misalnya begitu Anda mulai berbicara tentang perbankan investasi, dengan pengecualian melacak transaksi aktual, yang lainnya mengambang. Karena ini semua kode internal, Anda tidak akan melihatnya, tetapi Anda dapat mengambil puncak di QuantLib , yang pada dasarnya sama (kecuali jauh lebih bersih ;-).
Mengapa menggunakan pelampung? Karena menggunakan desimal tidak membantu sama sekali ketika Anda menggunakan fungsi seperti root kuadrat, logaritma, kekuatan dengan eksponen non-integer dll. Dan tentu saja mengapung jauh lebih cepat daripada tipe Desimal.
sumber
$100,000/12
dan menggunakan pelampung. Mengapa hasilnya persis $ 100.000? Mengapa float (atau desimal) tidak akan naik atau turun setiap kali seseorang dibayar? Saya berbicara tentang ketika menulis cek (Anda tidak dapat melakukan 1/2 atau 1/3 sen) atau setoran langsung (saya menganggap itu memiliki keterbatasan yang sama)Apa yang telah Anda gambarkan adalah pekerjaan yang sangat baik untuk situasi di mana Anda mengontrol semua input dan output .
Dalam kata sebenarnya bukan itu masalahnya. Anda harus dapat mengatasi sistem yang memasok data mereka kepada Anda sebagai nilai nyata hingga tingkat presisi tertentu dan akan mengharapkan Anda mengembalikan data dalam format yang sama. Dalam kasus seperti itu, Anda akan menghadapi masalah ini.
Bahkan Anda akan menghadapi masalah ini bahkan jika Anda menggunakan trik yang Anda daftarkan. Saat menghitung pajak 17,5% pada harga Anda akan mendapatkan sen pecahan apakah Anda menyimpan nilainya dalam dolar atau sen. Anda harus mendapatkan pembulatan yang benar karena petugas pajak menjadi sangat marah jika Anda tidak membayarnya cukup. Menggunakan
money
tipe-tipe yang benar (apa pun itu dalam bahasa yang Anda gunakan) akan menyelamatkan Anda dari dunia kesakitan.sumber
"Tuhan menciptakan bilangan bulat, yang lainnya adalah pekerjaan manusia." - Leopold Kronecker (1886).
Menurut definisi, Anda tidak memerlukan jenis angka lainnya. Kelengkapan Turing untuk bahasa pemrograman didasarkan pada hubungan sederhana di antara berbagai jenis angka. Jika Anda dapat bekerja dengan bilangan bulat (a / k / bilangan alami), Anda dapat melakukan apa saja.
Pertanyaannya agak membingungkan karena Anda tidak membutuhkannya . Mungkin Anda menginginkan tempat yang nyaman atau optimal atau lebih murah atau apa?
sumber
Dalam sebuah kalimat, tipe desimal floating-point merangkum konversi ke dan dari nilai integer (yang mana semua komputer tahu bagaimana berurusan dengan tingkat biner; tidak ada titik desimal dalam biner) yang menyediakan logika, umumnya mudah dilakukan. memahami antarmuka untuk perhitungan angka desimal.
Terus terang, mengatakan bahwa Anda tidak perlu mengapung karena Anda tahu bagaimana melakukan matematika desimal menggunakan bilangan bulat seperti mengatakan Anda tahu bagaimana melakukan aritmatika secara langsung, jadi mengapa menggunakan kalkulator? Jadi, Anda tahu konsepnya; bravo. Tidak berarti Anda harus menggunakan pengetahuan itu setiap saat. Seringkali lebih cepat, lebih murah, dan lebih mudah dipahami oleh jagoan non-biner untuk hanya mengatakan 3,5 + 4,6 = 8,1 daripada mengubah gambar ara ke kuantitas integer.
sumber
Keuntungan utama tipe floating-point adalah bahwa dari perspektif run-time, dua atau tiga format (saya berharap lebih banyak bahasa mendukung format 80-bit) akan mencukupi untuk sebagian besar tujuan komputasi yang cepat. Jika bahasa pemrograman dapat dengan mudah mendukung keluarga jenis titik tetap, kompleksitas perangkat keras yang diperlukan untuk tingkat kinerja tertentu akan sering lebih rendah dengan jenis titik tetap daripada dengan titik mengambang. Sayangnya, memberikan dukungan seperti itu masih jauh dari "mudah".
Agar suatu bahasa pemrograman dapat memenuhi 98% kebutuhan numerik aplikasi secara efisien, ia harus menyertakan lusinan jenis, dan menyediakan operasi yang pasti untuk ratusan kombinasi; lebih lanjut, bahkan jika bahasa pemrograman memiliki dukungan titik tetap yang luar biasa, beberapa aplikasi masih perlu mempertahankan presisi relatif yang relatif konstan pada rentang yang cukup besar sehingga memerlukan titik-mengambang. Mengingat bahwa matematika titik-mengambang akan diperlukan pada beberapa kesempatan dalam peristiwa apa pun, memiliki vendor perangkat keras fokus pada kinerja matematika dengan dua atau tiga format titik-mengambang, dan memiliki kode yang menggunakan format-format itu setiap kali mereka bekerja dengan cukup baik, umumnya akan mencapai yang lebih baik "bang for the buck" daripada mencoba mengoptimalkan perilaku matematika fixed-point.
Kebetulan, matematika fixed-point lebih menguntungkan dengan prosesor 8-bit dan 16-bit daripada dengan yang 32-bit. Pada prosesor 8-bit, dalam situasi di mana 32 bit tidak akan cukup, tipe 40-bit hanya akan menghabiskan biaya 25% lebih banyak ruang dan 25-50% lebih banyak waktu daripada tipe 32-bit, dan akan membutuhkan 37,5% lebih sedikit ruang dan waktu 37,5-60% lebih sedikit daripada tipe 64-bit. Pada platform 32-bit, jika tipe 32-bit tidak cukup untuk sesuatu, seringkali ada sedikit alasan untuk menggunakan sesuatu yang kurang dari 64 bit. Jika tipe titik tetap 48-bit akan memadai, "ganda" 64-bit akan berfungsi sama baiknya dengan tipe titik tetap.
sumber
Secara umum, Anda harus sangat berhati-hati dalam menggunakannya. Memahami hilangnya ketepatan yang dapat timbul bahkan dari perhitungan sederhana adalah sebuah tantangan. Misalnya, rata-rata daftar angka seperti ini adalah ide yang sangat buruk:
Alasannya adalah, untuk daftar yang cukup besar, Anda pada dasarnya kehilangan semua titik data ketika
ans
menjadi cukup besar (lihat misalnya ini ). Masalah dengan kode ini adalah bahwa untuk daftar kecil, itu mungkin hanya akan berfungsi --- itu hanya pada skala yang rusak.Secara pribadi, saya pikir Anda hanya boleh menggunakannya ketika: a) perhitungannya harus cepat; b) Anda tidak peduli bahwa hasilnya cenderung jauh (kecuali Anda benar-benar tahu apa yang Anda lakukan).
sumber
Satu pemikiran adalah bahwa Anda akan menggunakan representasi float atau dobel ketika Anda perlu berurusan dengan nilai-nilai di luar rentang integer.
Arsitektur hari ini (secara kasar) memiliki kisaran integer bertanda +/- 2.147.483.647 (32 bit) atau +/- 9.222.372.036.854.775.807 (64 bit). Unsigned memperluasnya dengan faktor 2.
IEEE 754 mengapung (kira-kira) naik dari +/- 1,4 × 10 ^ −45 ke 3,4 × 10 ^ 38. Double memanjang hingga +/- 5 × 10−324 ± 2.225 × 10 ^ −308 dengan banyak kondisi dan spesifikasi dihilangkan di sini.
Tentu saja, alasan yang paling jelas adalah bahwa Anda mungkin perlu mewakili -0 ;-)
sumber
Alasan biasa adalah karena mereka cepat karena JVM biasanya menggunakan dukungan perangkat keras yang mendasarinya (kecuali Anda menggunakan strictfp).
Lihat https://stackoverflow.com/questions/517915/when-to-use-strictfp-keyword-in-java untuk apa yang disiratkan strictfp.
sumber
Itu sebabnya kami membutuhkan sistem operasi 256bit.
Panjang Plank (jarak terkecil yang bisa Anda ukur) = 10 ^ -35m
Alam semesta yang dapat diamati adalah parsecs sepanjang 14Bn = 10 ^ 25m
Jadi Anda bisa mengukur apa pun dalam satuan panjang Plank sebagai bilangan bulat jika Anda hanya memiliki presisi 200 bit.
sumber