Kapan Anda menggunakan float dan kapan Anda menggunakan double

194

Seringkali dalam pengalaman pemrograman saya, saya perlu membuat keputusan apakah saya harus menggunakan float atau double untuk bilangan real saya. Terkadang saya mencoba float, terkadang saya double, tapi sebenarnya ini terasa lebih subyektif. Jika saya akan dihadapkan untuk membela keputusan saya, saya mungkin tidak akan memberikan alasan yang masuk akal.

Kapan Anda menggunakan float dan kapan Anda menggunakan double? Apakah Anda selalu menggunakan ganda, hanya ketika kendala memori hadir Anda pergi untuk float? Atau Anda selalu menggunakan float kecuali persyaratan presisi mengharuskan Anda menggunakan double? Apakah ada beberapa perbedaan substansial mengenai kompleksitas komputasi dari aritema dasar antara float dan double? Apa pro dan kontra menggunakan float atau double? Dan apakah Anda bahkan menggunakan double panjang?

Jakub Zaverka
sumber
28
Dalam banyak kasus, Anda tidak ingin menggunakan keduanya, melainkan tipe floating desimal atau fixedpoint. Tipe floating biner tidak dapat mewakili sebagian besar desimal.
CodesInChaos
3
Terkait dengan Apa yang menyebabkan kesalahan pembulatan floating point? . @CodesInChaos jawaban saya di sana menyarankan sumber daya untuk membantu Anda membuat keputusan itu, tidak ada solusi satu ukuran untuk semua .
Mark Booth
Jawaban yang sangat bagus ditemukan di: Stack Overflow
Haris
5
Apa yang sebenarnya Anda maksud dengan "desimal". Jika Anda perlu merepresentasikan nilai-nilai seperti 0,01 persis (katakanlah, untuk uang), maka (binary) floating-point bukanlah jawabannya. Jika Anda hanya bermaksud bilangan non-bilangan bulat, maka floating-point kemungkinan ok - tetapi "desimal" bukanlah kata terbaik untuk menggambarkan apa yang Anda butuhkan.
Keith Thompson
1
Anda tidak selalu punya pilihan. Misalnya, pada platform Arduino, baik float ganda maupun float sama dengan float. Anda perlu menemukan pustaka tambahan untuk menangani ganda nyata.
kiwiron

Jawaban:

187

Pilihan default untuk tipe floating-point seharusnya double. Ini juga merupakan jenis yang Anda dapatkan dengan literal titik mengambang tanpa akhiran atau fungsi standar (dalam C) yang beroperasi pada angka titik mengambang (mis exp. sin, Dll.).

float seharusnya hanya digunakan jika Anda perlu beroperasi pada banyak angka floating-point (pikirkan dalam urutan ribuan atau lebih) dan analisis algoritme telah menunjukkan bahwa rentang dan akurasi yang berkurang tidak menimbulkan masalah.

long doubledapat digunakan jika Anda membutuhkan jangkauan atau keakuratan lebih dari double, dan jika ia menyediakan ini pada platform target Anda.

Singkatnya, floatdan long doubleharus disediakan untuk digunakan oleh spesialis, dengan doubleuntuk penggunaan "setiap hari".

Bart van Ingen Schenau
sumber
10
Saya mungkin tidak akan mempertimbangkan float untuk beberapa ribu nilai kecuali ada masalah kinerja yang terkait dengan caching floating point dan transfer data. Biasanya ada biaya besar untuk melakukan analisis untuk menunjukkan bahwa float cukup tepat.
Patricia Shanahan
4
Sebagai tambahan, jika Anda memerlukan kompatibilitas dengan sistem lain, akan menguntungkan jika menggunakan tipe data yang sama.
zzzzBov
15
Saya akan menggunakan pelampung untuk jutaan angka, bukan 1000-an. Juga, beberapa GPU bekerja lebih baik dengan float, dalam hal itu penggunaan float khusus. Lain, seperti yang Anda katakan, gunakan ganda.
user949300
4
@ PatriciaShanahan - 'masalah kinerja yang terkait dengan ..' Contoh yang baik adalah jika Anda berencana untuk menggunakan SSE2 atau instruksi vektor serupa, Anda dapat melakukan 4 ops / vektor dalam float (vs 2 per ganda) yang dapat memberikan peningkatan kecepatan yang signifikan ( setengah lebih banyak ops dan separuh lebih banyak data untuk dibaca & ditulis). Ini secara signifikan dapat menurunkan ambang di mana penggunaan float menjadi menarik, dan layak untuk menyelesaikan masalah numerik.
greggo
12
Saya mendukung jawaban ini dengan satu saran tambahan: Ketika seseorang beroperasi dengan nilai RGB untuk tampilan, dapat diterima untuk digunakan float(dan kadang-kadang setengah presisi) karena mata manusia, layar, atau sistem warna tidak memiliki banyak bit presisi. . Saran ini berlaku untuk mengatakan OpenGL dll. Saran tambahan ini tidak berlaku untuk gambar medis, yang memiliki persyaratan presisi yang lebih ketat.
rwong
42

Jarang ada alasan untuk menggunakan float alih-alih menggandakan kode yang menargetkan komputer modern. Ketepatan ekstra mengurangi (tetapi tidak menghilangkan) kemungkinan kesalahan pembulatan atau masalah lainnya yang menyebabkan ketidaktepatan.

Alasan utama yang bisa saya pikirkan untuk menggunakan float adalah:

  1. Anda menyimpan jumlah array yang besar dan perlu mengurangi konsumsi memori program Anda.
  2. Anda menargetkan sistem yang tidak mendukung floating point presisi ganda. Sampai saat ini, banyak kartu grafis hanya mendukung floating point presisi tunggal. Saya yakin ada banyak prosesor dengan daya rendah dan tertanam yang memiliki dukungan floating point yang terbatas juga.
  3. Anda menargetkan perangkat keras di mana presisi tunggal lebih cepat daripada presisi ganda, dan aplikasi Anda banyak menggunakan aritmatika floating point. Pada CPU Intel modern saya percaya semua perhitungan floating point dilakukan dalam presisi ganda, jadi Anda tidak mendapatkan apa pun di sini.
  4. Anda melakukan optimasi tingkat rendah, misalnya menggunakan instruksi CPU khusus yang beroperasi pada beberapa nomor sekaligus.

Jadi, pada dasarnya, gandakan adalah cara untuk pergi kecuali Anda memiliki keterbatasan perangkat keras atau kecuali analisis telah menunjukkan bahwa menyimpan angka presisi ganda berkontribusi signifikan terhadap penggunaan memori.

pengguna611910
sumber
2
"Komputer modern" yang berarti prosesor Intel x86. Beberapa mesin yang digunakan dahulu memberikan presisi yang cukup memadai dengan tipe dasar mengambang. (CDC 6600 menggunakan kata 60-bit, 48 bit mantissa floating-point yang dinormalisasi, 12 bit eksponen. HAMPIR apa yang diberikan x86 untuk presisi ganda.)
John R. Strohm
@ John.R.Strohm: setuju, tetapi kompiler C tidak ada di CDC6600. Itu adalah Fortran IV ...
Basile Starynkevitch
Yang saya maksud dengan "komputer modern" adalah prosesor apa pun yang dibangun dalam satu atau dua dekade terakhir, atau benar-benar, sejak standar floating point IEEE diterapkan secara luas. Saya sangat menyadari bahwa arsitektur non-x86 ada dan memikirkan jawaban saya - saya menyebutkan GPU dan prosesor tertanam, yang biasanya bukan x86.
user611910
Tapi itu tidak benar. SSE2 dapat memanipulasi 4 float atau 2 double dalam satu operasi, AVX dapat memanipulasi 8 float atau 4 double, AVX-512 dapat memanipulasi 16 float atau 8 double. Untuk segala jenis komputasi kinerja tinggi, matematika pada mengapung harus dianggap sebagai dua kali kecepatan operasi yang sama pada ganda di x86.
Larry Gritz
1
Dan itu bahkan lebih buruk dari itu, karena Anda dapat memuat cache prosesor dua kali lebih banyak daripada yang Anda bisa dengan ganda, dan latensi memori cenderung menjadi hambatan utama dalam banyak program. Menjaga seluruh rangkaian float agar tetap hangat dalam cache mungkin secara harfiah lebih cepat daripada menggunakan ganda dan membuatnya tumpah ke RAM.
Larry Gritz
10

Gunakan doubleuntuk semua perhitungan Anda dan variabel temp. Gunakan floatsaat Anda perlu mempertahankan array angka - float[](jika presisi memadai), dan Anda berurusan dengan lebih dari puluhan ribu floatangka.

Banyak / sebagian besar fungsi matematika atau operator mengonversi / mengembalikan double, dan Anda tidak ingin mengembalikan angka ke floatuntuk langkah perantara apa pun.

Misalnya. Jika Anda memiliki input 100.000 angka dari file atau streaming dan perlu mengurutkannya, masukkan angka dalam a float[].

Fai Ng
sumber
5

Beberapa platform (ARM Cortex-M2, Cortex-M4 dll) tidak mendukung dobel (Ini selalu dapat diperiksa di manual referensi untuk prosesor Anda. Jika tidak ada peringatan kompilasi atau kesalahan, itu tidak berarti bahwa kode optimal. ganda dapat ditiru.). Itu sebabnya Anda mungkin harus tetap menggunakan int atau mengapung .

Jika bukan itu masalahnya, saya akan menggunakan ganda .

Anda dapat memeriksa artikel terkenal oleh D. Goldberg ("Apa Yang Harus Diketahui Setiap Ilmuwan Komputer Tentang Aritmatika Titik Apung"). Anda harus berpikir dua kali sebelum menggunakan aritmatika floating-point. Ada kemungkinan besar mereka tidak diperlukan sama sekali dalam situasi khusus Anda.

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

staroselskii
sumber
3
Pertanyaan ini sudah dijawab dengan cukup baik setahun yang lalu ... tetapi dalam hal apa pun, saya katakan kapan saja Anda menggunakan platform ganda dengan akselerasi FPU ganda presisi, Anda harus menggunakannya pada yang lain, bahkan jika itu berarti membiarkan kompilator mengemulasi alih-alih mengambil keuntungan dari FPU dengan floating-point saja (perhatikan bahwa FPU tidak diperlukan pada semua platform, bahkan arsitektur Cortex-M4 mendefinisikannya sebagai fitur opsional [apakah M2 salah ketik?] ).
Selali Adobor
Kunci dari logika itu adalah, sementara itu benar orang harus lelah dengan aritmatika floating point, dan itu banyak "quirks", jelas tidak mengambil kehadiran dukungan FPU untuk ganda berarti hanya menggunakan ganda bukan mengapung. Mengapung secara umum lebih cepat daripada ganda dan mengambil lebih sedikit memori (fitur FPU bervariasi). Volume penggunaan menghalangi titik ini untuk berada pada optimasi prematur. Seperti halnya fakta ganda jelas-jelas berlebihan untuk banyak (bahkan mungkin sebagian besar) aplikasi. Apakah elemen-elemen pada halaman ini benar-benar harus memiliki posisi relatif dan ukurannya dihitung hingga 13 tempat desimal?
Selali Adobor
2
Saat menyertakan tautan ke halaman luar atau dokumen, harap salin informasi yang relevan, atau ringkasan, dari dokumen ke dalam jawaban Anda. Tautan di luar situs cenderung menghilang seiring waktu.
Adam Zuckerman
3

Untuk masalah dunia nyata, ambang batas pengambilan sampel data Anda penting saat menjawab pertanyaan ini. Demikian pula, lantai kebisingan juga penting. Jika salah satu terlampaui oleh pemilihan tipe data Anda, tidak akan ada manfaat dari meningkatnya presisi.

Kebanyakan sampler dunia nyata terbatas pada 24 bit DAC s. Menyarankan bahwa 32 bit presisi pada perhitungan dunia nyata harus memadai di mana signifikansinya adalah 24 bit presisi.

Presisi ganda datang dengan biaya 2x memori. Oleh karena itu membatasi penggunaan doubles over float dapat secara drastis memotong jejak memori / bandwidth dari aplikasi yang sedang berjalan.

pengguna3034617
sumber
-3

Pilihan variabel apa yang digunakan antara float dan double tergantung pada keakuratan data yang diperlukan. Jika suatu jawaban diperlukan untuk memiliki perbedaan yang dapat diabaikan dari jawaban yang sebenarnya, jumlah tempat desimal yang diperlukan akan banyak sehingga akan menentukan bahwa dua kali lipat akan digunakan. Float akan memotong beberapa bagian tempat desimal sehingga mengurangi akurasi.

David Monyancha
sumber
3
Jawaban ini tidak menambahkan sesuatu yang baru pada pertanyaan, dan gagal mengatakan apa pun tentang penggunaan aktual.
Martijn Pieters
-5

Biasanya, saya menggunakan floattipe ketika saya tidak membutuhkan banyak ketepatan - misalnya, untuk uang - yang salah, tetapi apa yang saya lakukan salah lakukan.

Di sisi lain, saya gunakan doubleketika saya membutuhkan lebih banyak ketepatan, misalnya untuk algoritma matematika yang kompleks.

Standar C99 mengatakan ini:

Ada tiga jenis floating point: float, double, dan long double. Jenis ganda memberikan setidaknya presisi sebanyak float, dan jenis panjang ganda memberikan setidaknya sebanyak presisi sebagai ganda. Himpunan nilai tipe float adalah himpunan bagian dari himpunan nilai tipe ganda; himpunan nilai dari tipe ganda adalah himpunan bagian dari himpunan nilai dari tipe double panjang.

Saya tidak pernah benar-benar menggunakan long double, tetapi saya tidak menggunakan C / C ++ begitu banyak. Biasanya saya menggunakan bahasa yang diketik secara dinamis seperti Python, di mana Anda tidak perlu peduli dengan jenisnya.

Untuk informasi lebih lanjut tentang Double vs Float , lihat pertanyaan ini di SO .

Addison Montgomery
sumber
25
Menggunakan floating point untuk perhitungan uang yang serius mungkin merupakan kesalahan.
Bart van Ingen Schenau
17
float adalah jenis uang yang salah. Anda harus menggunakan presisi setinggi mungkin.
ChrisF
8
@BartvanIngenSchenau Floating point untuk uang biasanya oke, floating point biner tidak. Sebagai contoh .net Decimaladalah tipe floating point dan biasanya merupakan pilihan yang baik untuk perhitungan uang.
CodesInChaos
13
@ ChrisF Anda tidak perlu "presisi tinggi" untuk uang, Anda membutuhkan nilai yang tepat.
Sean McSomething
2
@SeanMcSomething - Titik adil. Namun, tipe float masih salah dan mengingat tipe floating point tersedia di sebagian besar bahasa, Anda memerlukan "presisi tinggi" untuk mendapatkan "nilai yang tepat".
ChrisF