Tidak, ini bukan pertanyaan "Kenapa (1 / 3.0) * 3! = 1" .
Saya telah membaca tentang floating-point akhir-akhir ini; khususnya, bagaimana perhitungan yang sama dapat memberikan hasil yang berbeda pada arsitektur yang berbeda atau pengaturan optimasi.
Ini adalah masalah untuk gim video yang menyimpan replay, atau jaringan peer-to-peer (bukan server-klien), yang mengandalkan semua klien yang menghasilkan hasil yang persis sama setiap kali mereka menjalankan program - perbedaan kecil dalam satu perhitungan floating-point dapat menyebabkan kondisi permainan yang sangat berbeda pada mesin yang berbeda (atau bahkan pada mesin yang sama! )
Ini terjadi bahkan di antara prosesor yang "mengikuti" IEEE-754 , terutama karena beberapa prosesor (yaitu x86) menggunakan presisi ganda yang diperluas . Artinya, mereka menggunakan register 80-bit untuk melakukan semua perhitungan, kemudian memotong ke 64- atau 32-bit, yang mengarah ke hasil pembulatan yang berbeda dari mesin yang menggunakan 64- atau 32-bit untuk perhitungan.
Saya telah melihat beberapa solusi untuk masalah ini secara online, tetapi semua untuk C ++, bukan C #:
- Nonaktifkan mode presisi diperluas ganda (sehingga semua
double
perhitungan menggunakan IEEE-754 64-bit) menggunakan_controlfp_s
(Windows),_FPU_SETCW
(Linux?), Ataufpsetprec
(BSD). - Selalu jalankan kompiler yang sama dengan pengaturan optimisasi yang sama, dan minta semua pengguna memiliki arsitektur CPU yang sama (tidak ada permainan lintas platform). Karena "kompiler" saya sebenarnya adalah JIT, yang dapat mengoptimalkan secara berbeda setiap kali program dijalankan , saya rasa ini tidak mungkin.
- Gunakan aritmatika titik tetap, dan hindari
float
dandouble
sama sekali.decimal
akan bekerja untuk tujuan ini, tetapi akan jauh lebih lambat, dan tidak adaSystem.Math
fungsi perpustakaan yang mendukungnya.
Jadi, apakah ini bahkan masalah di C #? Bagaimana jika saya hanya bermaksud mendukung Windows (bukan Mono)?
Jika ya, apakah ada cara untuk memaksa program saya berjalan pada presisi ganda normal?
Jika tidak, apakah ada perpustakaan yang akan membantu menjaga penghitungan floating-point konsisten?
strictfp
kata kunci, yang memaksa semua perhitungan dilakukan dalam ukuran yang ditentukan ( float
atau double
) daripada ukuran yang diperluas. Namun, Java masih memiliki banyak masalah dengan dukungan IEE-754. Sangat (sangat, sangat) sedikit bahasa pemrograman mendukung IEE-754 dengan baik.