Apakah saya masih perlu menggunakan titik tetap untuk menjamin komputer mendapatkan hasil yang sama untuk operasi matematika lagi?

9

Saya diberitahu bahwa kebanyakan komputer modern mengikuti standar floating point yang sama, apakah ini berarti mereka semua akan mendapatkan jawaban float yang sama untuk operasi matematika yang diberikan jika inputnya sama?

Saya bertanya karena saya sedang meneliti cara membuat game RTS di jaringan, dan menyinkronkan ratusan posisi unit terdengar seperti cara yang buruk.

Jadi jika saya hanya mengirim input saja, saya perlu menjamin semua klien mendapatkan hasil yang sama dengan meminta mereka menjalankan simulasi dari input tersebut.

Saya membaca bahwa game RTS yang lebih lama menggunakan aritmatika titik tetap, tetapi saya tidak tahu apakah itu masih diperlukan pada komputer modern jika semuanya mematuhi standar yang sama? Saya juga diberitahu bahwa meskipun tidak tepat, hasil floating point adalah deterministik untuk input yang sama (yang saya anggap komputer mana pun yang mengikuti standar yang sama mendapatkan hasil yang tidak tepat sama?).

Apakah komputer masih memiliki penyimpangan bahkan jika mereka mengikuti standar float point yang sama?

Saya menulis game ini di C # tidak yakin apakah itu penting, saya pikir saya akan menyebutkannya.

WDUK
sumber
Bahkan jika mereka melakukannya, saya tidak akan menggunakan pelampung untuk itu
Telastyn
Apa maksudmu ? Kenapa tidak?
WDUK
Penggunaan float mungkin tidak diinginkan karena perilaku mungkin tergantung pada posisi pada peta. Far Lands Minecraft adalah contoh yang lebih menonjol: gerakan, rendering, dan generasi medan akan menjadi sangat buruk saat Anda bergerak jauh dari titik spawn.
amon

Jawaban:

18

Apakah komputer masih memiliki penyimpangan bahkan jika mereka mengikuti standar float point yang sama?

Sayangnya, ya, terutama ketika Anda menggunakan C # (atau bahasa kompilasi JIT lain). Masalah yang terjadi di sini adalah bahwa tahap kompilasi JIT pada beberapa arsitektur prosesor menghasilkan kode yang menggunakan lebih banyak register CPU daripada pada arsitektur lain. Ini dapat menyebabkan situasi di mana pada beberapa mesin, presisi floating point yang diperluas digunakan untuk operasi tertentu, sedangkan pada mesin lain tidak. Ini berarti untuk setiap perhitungan berulang menggunakan ganda, ada kemungkinan untuk menghasilkan kesalahan pembulatan akumulasi yang berbeda.

Itu bukan masalah hipotetis, saya memiliki pengalaman langsung dengan penyimpangan dalam perangkat lunak simulasi rekayasa kontemporer, pada perangkat keras yang kurang lebih modern. Masalah ini membuatnya sangat sulit untuk membuat tes regresi yang andal untuk perhitungan floating point kompleks yang menghasilkan hasil yang persis sama pada semua mesin yang terlibat.

Doc Brown
sumber
Ini. Beberapa akar penyebab: IEEE Std 754 menyertakan klausul "harus" opsional (mis. Penanganan NaN) dan mengizinkan alternatif desain (mis. Deteksi underflow). Sejauh binding bahasa mendukung standar titik-mengambang, mereka masih dapat memberikan kelonggaran bagi kompiler ketika mengevaluasi ekspresi titik-mengambang, misalnya FLT_EVAL_METHODdalam ISO C / C ++. Fungsi transendental (mis sin. exp, log) Sebagian besar tidak diatur oleh standar titik-mengambang IEEE dan standar bahasa pemrograman. Pemutakhiran versi pustaka sederhana (mis. glibcVersi baru ) dapat menyebabkan hasil yang berbeda.
njuffa
Saya sudah memukulnya sendiri dalam sebuah game. Roket itu terbang dengan baik di laptop saya, tidak akan terbang di desktop saya, instalasi yang sama persis.
Loren Pechtel
3

Kesalahan Floating Point

Setiap angka floating point mengakumulasi ketidaktepatan karena digunakan untuk perhitungan. Ini adalah fakta sederhana menggunakan format yang tidak tepat untuk menghitung. Perhitungan juga sensitif terhadap urutan perhitungan, komutatifitas tidak dijamin, yaitu: (a + b) + cmungkin atau mungkin tidak sama dengan a + (b + c).

Selain itu prosesor tidak harus memiliki panjang mantissa yang sama dengan standar memori. Ini dapat menghasilkan perilaku yang menarik karena float 32/64/128 sesekali beroperasi seolah-olah mereka memiliki lebih banyak bit.

Memperbaiki Kesalahan Poin

Itu dikatakan titik tetap aritmatika juga dapat mengakumulasi kesalahan. Perbedaannya adalah bahwa angka-angka titik tetap jelas tentang presisi yang hilang, dan tergantung pada operasi yang dipilih dapat menghindari kesalahan pembulatan sama sekali. Mereka juga komutatif (a + b) + c = a + (b + c).

Yang?

Yang mana untuk digunakan tergantung sepenuhnya pada properti apa yang Anda butuhkan.

Nomor titik mengambang:

  • memberikan berbagai nilai yang menjadi butiran halus yang sangat dekat, dan semakin jauh terpisah pada ekstrem.
  • sensitif terhadap urutan perhitungan
  • mengakumulasi kesalahan pembulatan dari waktu ke waktu.
  • dapat memiliki perilaku tidak menentu karena ketidakcocokan ukuran float perangkat keras / memori.

Nomor Poin Tetap:

  • berikan rentang angka yang lebih kecil dengan jarak yang sama antara dua angka berurutan.
  • kurang sensitif terhadap urutan perhitungan
  • lebih jelas tentang kesalahan pembulatan
  • dapat dikerjakan dengan meminimalkan / menghindari masalah pembulatan.
Kain0_0
sumber
1
"angka titik tetap jelas tentang presisi yang hilang" - titik mengambang juga jelas, perbedaannya adalah ketidaktepatan titik tetap lebih intuitif untuk penomoran kehidupan biasa
whatsisname
1
Jadi hanya titik tetap yang menjamin semua komputer terlepas dari perangkat keras dll akan mengalami kesalahan yang sama / kehilangan presisi?
WDUK
1
Pada dasarnya, ya, karena Anda dapat menentukan bahwa nomor titik tetap Anda adalah 32 atau 64 bit, dan itu akan ada di semua sistem. Angka floating point mungkin 32 atau 64-bit, tetapi perangkat keras sebenarnya dapat menggunakan 48 atau 96 bit untuk melakukan perhitungan dan mengkonversi ke 32 atau 64 bit pada akhirnya menghasilkan perbedaan antara berbagai jenis perangkat keras.
user1118321
@whatsisname Sedangkan spesifikasi floating point yang cukup jelas, Anda tidak dapat dengan mudah menceritakan masalah apa pembulatan akan saya temui di sum ini: (a + b * c) / d - e. Kecuali masalah yang jelas seperti NaN, pembagian dengan nol, atau overflow / underflow adalah mungkin untuk ungkapan ini tidak benar. Tambahkan ke bahwa impedansi antara memori dan mendaftar dalam hal presisi dan bahkan memuat / menyimpan sederhana dari memori dari nilai floating point yang "sama" akan mengubah jawabannya.
Kain0_0
@ Kain0_0: Anda benar, saya tidak dapat dengan mudah memberi tahu Anda apa yang akan saya temui, karena saya bukan ahli floating point. Itulah yang dimaksud ketika saya mengatakan "lebih intuitif untuk penomoran kehidupan biasa". Ketika Anda mengatakan titik tetap "jelas" dan titik mengambang tidak, Anda membuatnya terdengar seolah-olah mengapung hanya tampaknya tidak akurat secara acak.
whatsisname
-1

Ada pertanyaan mengapa Anda ingin menjamin hasil yang identik, karena hasil yang sama tidak memberikan jaminan sama sekali bahwa hasil Anda bermanfaat .

Anda dapat memiliki algoritma yang tidak stabil secara numerik yang memberikan dua hasil yang identik tetapi sama sekali tidak masuk akal di komputer yang berbeda. Jika ada perbedaan, tetapi hasilnya sama dalam 13 digit, itu jauh lebih dapat dipercaya.

Ada beberapa situasi di mana reproduksibilitas sangat penting: dalam mesin tata letak, atau kompresi / dekompresi lossless. Menggunakan titik tetap sangat mungkin salah arah.

gnasher729
sumber
Saya tidak mengecilkan jawaban Anda, tetapi tampaknya kasus yang dijelaskan oleh OP persis "salah satu dari beberapa situasi di mana reproduktifitas sangat penting". Dalam game RTS, kesalahan pembulatan kecil dapat membuat perbedaan antara "dua objek bertabrakan" atau tidak.
Doc Brown