Haruskah saya menggunakan double atau float?


90

Apa keuntungan dan kerugian menggunakan salah satu daripada yang lain di C ++?


Adakah yang pernah mencoba membuat array float dan array double dan melihat apakah memang ada 4 byte antara anggota di float dan 8 byte di antara anggota di double? Ada kemungkinan bahwa kompiler / komputer 64bit mungkin masih mencadangkan 8 byte per anggota untuk float meskipun mereka tidak membutuhkannya terlalu banyak.
pengguna3015682

Jawaban:


104

Jika Anda ingin mengetahui jawaban yang benar, Anda harus membaca Yang Harus Diketahui Setiap Ilmuwan Komputer Tentang Aritmatika Titik-Apung .

Singkatnya, meskipun doublememungkinkan presisi yang lebih tinggi dalam penggambarannya, untuk kalkulasi tertentu hal itu akan menghasilkan kesalahan yang lebih besar . Pilihan yang "benar" adalah: gunakan presisi sebanyak yang Anda butuhkan tetapi tidak lebih dan pilih algoritma yang tepat .

Banyak kompiler melakukan matematika floating point yang diperluas dalam mode "non-ketat" (yaitu menggunakan jenis floating point yang lebih luas yang tersedia di perangkat keras, misalnya floating point 80-bit dan 128-bit), ini harus diperhitungkan juga. Dalam praktiknya, Anda hampir tidak dapat melihat perbedaan dalam kecepatan - bagaimanapun juga mereka asli dari perangkat keras.


10
Iya. Dengan CPU modern yang mengambil bagian memori yang lebih besar dan lebih besar, unit pemrosesan numerik paralel dan arsitektur pipelined, masalah kecepatan sebenarnya bukan masalah. Jika Anda berurusan dengan angka dalam jumlah besar, mungkin perbedaan ukuran antara float 4 byte dan double 8 byte mungkin membuat perbedaan dalam footprint memori.
lavinio

5
Sumur SSE (atau unit titik apung vertor) akan dapat memproses dua kali jumlah jepit dalam presisi tunggal dibandingkan dengan presisi ganda. Jika Anda hanya melakukan floating point x87 (atau skalar) maka itu mungkin tidak masalah.
Greg Rogers

1
@ Greg Rogers: kompiler tidak begitu pintar saat ini. Kecuali Anda menulis rakitan mentah, itu tidak memiliki perbedaan besar. Dan ya, ini mungkin berubah saat kompilator berkembang.
J-16 SDiZ

Catatan tambahan: Jika Anda sama sekali tidak tahu seperti apa datanya (atau sama sekali tidak tahu matematika di tautan), cukup gunakan double- ini lebih aman dalam banyak kasus.
J-16 SDiZ

@jokoon, tidak ada yang sederhana dalam floating point dan seluruh area masalah presisi / stabilitas numerik.
vonbrand

45

Kecuali jika Anda memiliki alasan khusus untuk melakukan sebaliknya, gunakan double.

Mungkin mengejutkan, ini adalah double dan bukan float yang merupakan tipe floating-point "normal" di C (dan C ++). Fungsi matematika standar seperti sin dan log mengambil ganda sebagai argumen, dan mengembalikan ganda. Literal floating-point normal, seperti ketika Anda menulis 3,14 di program Anda, memiliki tipe double. Tidak mengapung.

Pada komputer modern pada umumnya, penggandaan bisa secepat float, atau bahkan lebih cepat, sehingga kinerja biasanya bukan faktor yang perlu dipertimbangkan, bahkan untuk kalkulasi besar. (Dan itu harus menjadi perhitungan besar , atau kinerja tidak boleh terlintas dalam pikiran Anda. Komputer desktop i7 baru saya dapat melakukan enam miliar penggandaan ganda dalam satu detik.)


26

Pertanyaan ini tidak mungkin dijawab karena tidak ada konteks pertanyaannya. Berikut beberapa hal yang dapat memengaruhi pilihan:

  1. Implementasi penyusun float, double, dan long double. Standar C ++ menyatakan:

    Ada tiga tipe floating point: float, double, dan long double. Tipe ganda memberikan ketepatan sekurang-kurangnya sebanyak pelampung, dan tipe ganda panjang memberikan ketepatan sekurang-kurangnya sebanyak ganda.

    Jadi, ketiganya bisa memiliki ukuran yang sama di memori.

  2. Kehadiran FPU. Tidak semua CPU memiliki FPU dan terkadang tipe floating point diemulasi dan terkadang tipe floating point tidak didukung.

  3. Arsitektur FPU. FPU IA32 adalah 80bit secara internal - float 32 bit dan 64 bit diperluas menjadi 80bit saat dimuat dan dikurangi saat disimpan. Ada juga SIMD yang dapat melakukan empat float 32bit atau dua float 64bit secara paralel. Penggunaan SIMD tidak didefinisikan dalam standar sehingga akan membutuhkan kompilator yang melakukan analisis yang lebih kompleks untuk menentukan apakah SIMD dapat digunakan, atau memerlukan penggunaan fungsi khusus (perpustakaan atau intrinsik). Hasil dari format internal 80bit adalah Anda bisa mendapatkan hasil yang sedikit berbeda tergantung pada seberapa sering data disimpan ke RAM (dengan demikian, kehilangan presisi). Untuk alasan ini, kompiler tidak mengoptimalkan kode floating point dengan baik.

  4. Bandwidth memori. Jika double membutuhkan lebih banyak penyimpanan daripada float, maka akan membutuhkan waktu lebih lama untuk membaca data. Itulah jawaban yang naif. Pada IA32 modern, semuanya tergantung dari mana datanya berasal. Jika berada dalam cache L1, beban dapat diabaikan asalkan data berasal dari satu baris cache. Jika itu mencakup lebih dari satu baris cache, ada sedikit biaya tambahan. Jika dari L2, butuh waktu lebih lama, jika dalam RAM maka lebih lama diam dan akhirnya, jika di disk itu waktu yang sangat lama. Jadi pilihan float atau double kurang penting dibandingkan cara data digunakan. Jika Anda ingin melakukan penghitungan kecil pada banyak data sekuensial, tipe data kecil lebih disukai. Melakukan banyak komputasi pada kumpulan data kecil akan memungkinkan Anda menggunakan tipe data yang lebih besar dengan efek yang signifikan. Jika kamu' mengakses kembali data dengan sangat acak, maka pilihan ukuran data tidak penting - data dimuat di halaman / baris cache. Jadi, meskipun Anda hanya menginginkan satu byte dari RAM, Anda bisa mendapatkan 32 byte yang ditransfer (ini sangat bergantung pada arsitektur sistem). Di atas semua ini, CPU / FPU bisa sangat skalar (alias pipelined). Jadi, meskipun suatu beban mungkin memerlukan beberapa siklus, CPU / FPU mungkin sibuk melakukan sesuatu yang lain (kelipatan misalnya) yang menyembunyikan waktu muat sampai tingkat tertentu.

  5. Standar tidak memberlakukan format tertentu untuk nilai floating point.

Jika Anda memiliki spesifikasi, maka itu akan memandu Anda ke pilihan yang optimal. Jika tidak, tergantung pengalaman tentang apa yang harus digunakan.


16

Double lebih tepat tetapi diberi kode pada 8 byte. float hanya 4 byte, jadi lebih sedikit ruang dan kurang presisi.

Anda harus sangat berhati-hati jika Anda memiliki double dan float di aplikasi Anda. Saya punya bug karena itu di masa lalu. Salah satu bagian kode menggunakan float sedangkan bagian kode lainnya menggunakan double. Menyalin ganda untuk mengapung dan kemudian mengapung menjadi ganda dapat menyebabkan kesalahan presisi yang dapat berdampak besar. Dalam kasus saya, itu adalah pabrik kimia ... semoga tidak menimbulkan konsekuensi dramatis :)

Saya pikir karena bug semacam inilah roket Ariane 6 meledak beberapa tahun yang lalu !!!

Pikirkan baik-baik tentang tipe yang akan digunakan untuk variabel


3
Perhatikan bahwa 4/8 byts untuk float / double bahkan tidak dijamin, itu akan tergantung pada platformnya. Bahkan mungkin tipe yang sama ...
sleske

2
Kode Ariane 5 mencoba mengubah 64 bit floating point, yang nilainya lebih besar dari 32.767, menjadi integer bertanda tangan 16 bit. Ini menghasilkan pengecualian overflow yang menyebabkan roket memulai urutan penghancurannya sendiri. Kode yang dimaksud, adalah kode yang digunakan kembali dari roket yang lebih tua dan lebih kecil.
cmwt

5

Saya secara pribadi berusaha mendapatkan dua kali lipat setiap saat sampai saya melihat beberapa kemacetan. Kemudian saya mempertimbangkan untuk pindah ke float atau mengoptimalkan beberapa bagian lainnya


4

Ini tergantung pada bagaimana kompilator mengimplementasikan double. Itu legal untuk double dan float menjadi tipe yang sama (dan itu ada pada beberapa sistem).

Bisa dikatakan, jika memang berbeda, masalah utamanya adalah presisi. Ganda memiliki presisi yang jauh lebih tinggi karena perbedaan ukurannya. Jika angka yang Anda gunakan biasanya melebihi nilai float, gunakan double.

Beberapa orang lain telah menyebutkan masalah kinerja. Itu akan menjadi yang terakhir dalam daftar pertimbangan saya. Ketepatan harus menjadi pertimbangan # 1 Anda.



2

Saya pikir terlepas dari perbedaannya (yang seperti yang ditunjukkan semua orang, float mengambil lebih sedikit ruang dan secara umum lebih cepat) ... apakah ada yang pernah mengalami masalah kinerja saat menggunakan double? Saya katakan gunakan ganda ... dan jika nanti Anda memutuskan "wow, ini benar-benar lambat" ... temukan hambatan kinerja Anda (yang mungkin bukan fakta Anda menggunakan ganda). LALU, jika masih terlalu lambat untuk Anda, lihat di mana Anda dapat mengorbankan beberapa presisi dan menggunakan pelampung.



1

Itu sangat bergantung pada CPU, trade-off yang paling jelas adalah antara presisi dan memori. Dengan GB RAM, memori tidak terlalu menjadi masalah, jadi biasanya lebih baik untuk digunakandouble s.

Sedangkan untuk kinerja, ini sangat bergantung pada CPU. floatBiasanya s akan mendapatkan kinerja yang lebih baik daripada doubles pada mesin 32 bit. Pada 64 bit, doubles terkadang lebih cepat, karena ini (biasanya) adalah ukuran aslinya. Namun, yang lebih penting daripada pilihan tipe data Anda adalah apakah Anda dapat memanfaatkan instruksi SIMD pada prosesor Anda atau tidak.


0

double memiliki presisi yang lebih tinggi, sedangkan float menggunakan lebih sedikit memori dan lebih cepat. Secara umum Anda harus menggunakan float kecuali Anda memiliki kasus yang tidak cukup akurat.


5
Pada komputer modern yang khas, double sama cepatnya dengan float.
Thomas Padron-McCarthy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.