Kapan saya harus menggunakan kata kunci “strictfp” di java?

258

Saya sudah mencari tahu apa artinya ini, tetapi apakah ada yang benar-benar memiliki contoh kapan Anda akan menggunakan strictfpkata kunci di Jawa? Adakah yang benar-benar menemukan kegunaan untuk ini?

Apakah akan ada efek samping dari hanya meletakkannya di semua operasi floating point saya?

GBa
sumber
1
Selalu, kecuali Anda benar-benar membutuhkan kinerja lebih dari yang Anda butuhkan reproduksi.
Antimony
1
@Antimony - atau ketepatan / kebenaran. x86 / x64, misalnya, gunakan register floating point 80-bit secara internal, sehingga hasilnya akan lebih akurat untuk perhitungan panjang tanpa ff ketat.
Robert Fraser
1
@ Robert Sebenarnya, spesifikasi ini menjamin presisi terbatas dari mantissa. Satu-satunya perbedaan adalah bahwa ia dapat menggunakan presisi eksponen yang lebih besar dari biasanya, yang memiliki perbedaan dalam kasus yang jarang terjadi karena pembulatan ganda.
Antimony
Saya berpikir bahwa selain opsi untuk menaburkan pengubah yang berguna ini di seluruh sambungan, sfloat baru & sdouble data primitif strictfp mungkin merupakan ide yang bagus.
theRiley

Jawaban:

274

Strictfp memastikan Anda mendapatkan hasil yang persis sama dari perhitungan floating point Anda di setiap platform. Jika Anda tidak menggunakan strictfp, implementasi JVM bebas menggunakan presisi ekstra jika tersedia.

Dari JLS :

Dalam ekspresi FP-ketat, semua nilai menengah harus elemen elemen nilai float atau nilai ganda, yang menyiratkan bahwa hasil dari semua ekspresi FP-ketat harus yang diprediksi oleh IEEE 754 aritmatika pada operan yang diwakili menggunakan format tunggal dan ganda . Dalam ekspresi yang tidak ketat terhadap FP, beberapa kelonggaran diberikan bagi implementasi untuk menggunakan rentang eksponen yang diperluas untuk mewakili hasil antara; efek bersihnya, secara kasar, adalah bahwa suatu kalkulasi mungkin menghasilkan "jawaban yang benar" dalam situasi di mana penggunaan eksklusif dari nilai float set atau nilai ganda set mungkin menghasilkan overflow atau underflow.

Dengan kata lain, ini tentang memastikan bahwa Write-Once-Run-Anywhere sebenarnya berarti Write-Once-Get-Equally-Wrong-Results-Everywhere .

Dengan tightfp, hasil Anda portabel, tanpanya kemungkinan besar akan akurat.

Dan Dyer
sumber
28
Gunakan untuk hasil ilmiah yang dapat direproduksi dan tes unit bit-tepat.
Aleksandr Dubinsky
1
"Jika Anda tidak menggunakan strictfp, implementasi JVM bebas menggunakan presisi ekstra jika tersedia" - Anda membuatnya terdengar seperti hal yang buruk: P
AMDG
@LinkTheProgrammer tentu saja bisa menjadi hal yang buruk
Tim
@TimCastelijns Saya kira Happy Wheels adalah referensi Anda? Rekaman ulangi penekanan tombol; karena keragaman presisi implementasi FP-matematika, replay hanya akurat pada perangkat keras yang sama. Bisakah Anda menyebutkan masalah yang lebih realistis yang disebabkan oleh variabilitas matematika floating point? Saya bisa membayangkan mungkin simulator partikel, tapi apa lagi?
AMDG
Jadi ini berarti kita harus selalu menggunakan strictfp dalam produksi di mana banyak platform terlibat?
beatrice
65

Wikipedia sebenarnya memiliki artikel bagus tentang topik ini di sini , dengan tautan ke spesifikasi Java.

Membaca yang tersirat, implikasinya adalah bahwa jika Anda tidak menentukan strictfp, maka kompiler JVM dan JIT memiliki lisensi untuk menghitung perhitungan floating-point Anda seperti yang mereka inginkan. Untuk kepentingan kecepatan, mereka kemungkinan besar akan mendelegasikan perhitungan ke prosesor Anda. Dengan strictfpon, perhitungan harus sesuai dengan standar aritmetika IEEE 754, yang, dalam praktiknya, mungkin berarti bahwa JVM akan melakukan perhitungan.

Jadi mengapa Anda ingin menggunakannya strictfp? Satu skenario yang bisa saya lihat adalah dalam aplikasi terdistribusi (atau game multi-pemain) di mana semua perhitungan floating-point harus deterministik tidak peduli apa perangkat keras atau CPU yang mendasarinya. Apa untungnya? Kemungkinan besar waktu eksekusi.

MattK
sumber
5
"Rentang eksponen yang diperluas untuk mewakili hasil antara" bukan "lisensi untuk menghitung perhitungan floating-point Anda seperti yang mereka inginkan", dan dalam praktiknya, bahkan strictfpperhitungan menggunakan FPU 8087 yang bahkan tidak membantu. Hanya perlu sedikit perawatan yang diperlukan saat itu. Lihat stackoverflow.com/questions/18496560/…
Pascal Cuoq
Saya setuju dengan @PascalCuoq re: "lisensi untuk menghitung perhitungan floating-point Anda seperti yang mereka inginkan" . Jika ada, kebalikannya tampaknya benar dalam kasus ini, karena strictfpmemastikan kepatuhan dengan standar IEEE 754 (sehingga Anda mendapatkan hasil yang sama di semua platform). Satu-satunya kekurangan yang bisa saya lihat adalah bahwa Anda mungkin kehilangan manfaat memiliki FPU yang benar-benar bagus di perangkat keras asli Anda.
typeracer
25

Semuanya dimulai dengan sebuah cerita,

Ketika java sedang dikembangkan oleh James Gosling, Herbert dan seluruh timnya. Mereka memiliki hal gila ini dalam pikiran yang disebut independensi platform . Mereka ingin membuat pohon ek (Jawa)jauh lebih baik bahwa itu akan berjalan persis sama pada mesin apa pun yang memiliki set instruksi berbeda, bahkan menjalankan sistem operasi yang berbeda. Tapi, ada masalah dengan angka titik desimal yang juga dikenal sebagai floating point dan double dalam bahasa pemrograman. Beberapa mesin dibangun dengan efisiensi penargetan sedangkan sisanya menargetkan akurasi. Jadi, mesin yang lebih baru (lebih akurat) memiliki ukuran titik apung 80 bit sedangkan mesin yang sebelumnya (lebih efisien / lebih cepat) memiliki ganda 64 bit. Tapi, ini bertentangan dengan ide inti membangun platform bahasa yang independen. Juga, ini dapat menyebabkan hilangnya presisi / data ketika kode dibangun pada beberapa mesin (memiliki ukuran ganda 64 bit) dan dijalankan pada jenis mesin lain (memiliki ukuran ganda 80 bit).

Up-Sizing dapat ditoleransi tetapi Down-Sizing tidak bisa. Jadi, mereka menemukan konsep tightfp yaitu floating point yang ketat . Jika Anda menggunakan kata kunci ini dengan kelas / fungsi maka floating point dan dobelnya memiliki ukuran yang konsisten di semua mesin. yaitu masing-masing 32/64-bit.

AbimanyuAryan
sumber
8
strictfp diperkenalkan di Java 1.2. Ini jauh lebih lambat daripada ketika pohon ek dirancang.
Thorbjørn Ravn Andersen
"angka titik desimal juga dikenal sebagai titik mengambang" - Desimal berarti basis 10, dan tidak ada hubungannya dengan representasi titik mengambang.
aioobe
21

Berikut ini beberapa referensi:

  • Menggunakan strictfp (JDC Tech Tip)
  • jGuru: Untuk apa modifier strictfp? Kapan saya akan mempertimbangkan menggunakannya?

    Pada dasarnya, intinya adalah apakah Anda peduli atau tidak bahwa hasil ekspresi floating-point dalam kode Anda cepat atau dapat diprediksi. Misalnya, jika Anda memerlukan jawaban yang muncul dengan kode Anda yang menggunakan nilai floating-point agar konsisten di beberapa platform, gunakan strictfp.

  • strictfp - Daftar Istilah Java

    Perangkat keras floating point menghitung dengan lebih presisi, dan dengan rentang nilai yang lebih besar daripada yang dibutuhkan spesifikasi Java. Akan membingungkan jika beberapa platform memberikan presisi lebih dari yang lain. Ketika Anda menggunakan strictfppengubah pada metode atau kelas, kompiler menghasilkan kode yang secara ketat mengikuti spesifikasi Java untuk hasil yang identik pada semua platform. Tanpa strictfp, apakah itu sedikit lebih longgar, tetapi tidak begitu longgar untuk menggunakan bit penjaga di Pentium untuk memberikan 80 bit presisi.

  • Dan akhirnya Spesifikasi Bahasa Jawa yang sebenarnya, §15.4 Ekspresi ketat FP :

    Dalam ekspresi FP-ketat, semua nilai menengah harus elemen elemen nilai float atau nilai ganda, yang menyiratkan bahwa hasil dari semua ekspresi FP-ketat harus yang diprediksi oleh IEEE 754 aritmatika pada operan yang diwakili menggunakan format tunggal dan ganda . Dalam ekspresi yang tidak ketat terhadap FP, beberapa kelonggaran diberikan bagi implementasi untuk menggunakan rentang eksponen yang diperluas untuk mewakili hasil antara; efek bersihnya, secara kasar, adalah bahwa suatu kalkulasi mungkin menghasilkan "jawaban yang benar" dalam situasi di mana penggunaan eksklusif dari nilai float set atau nilai ganda set mungkin menghasilkan overflow atau underflow.

Namun, secara pribadi saya tidak pernah menggunakannya.

Michael Myers
sumber
12

Seperti jawaban lain yang disebutkan itu menyebabkan hasil floating point menengah sesuai dengan spesifikasi IEEE. Khususnya prosesor x86 dapat menyimpan hasil antara dengan presisi berbeda dari spesifikasi IEEE. Situasi menjadi lebih rumit ketika JIT mengoptimalkan perhitungan tertentu; urutan instruksi bisa berbeda setiap kali menghasilkan pembulatan yang sedikit berbeda.

Biaya overhead yang dikeluarkan oleh strictfp cenderung sangat tergantung pada prosesor dan JIT. Artikel wikipedia ini pada SSE2 tampaknya memiliki beberapa wawasan tentang masalah ini. Jadi jika JIT dapat menghasilkan instruksi SSE untuk melakukan perhitungan, sepertinya strictfp tidak akan memiliki overhead.

Dalam proyek saya saat ini ada beberapa tempat di mana saya menggunakan strictfp. Ada titik di mana potensi sinar kosmik perlu dihapus dari nilai piksel. Jika beberapa peneliti luar memiliki nilai piksel dan sinar kosmik yang sama di depannya, mereka akan mendapatkan nilai hasil yang sama dengan perangkat lunak kami.

Sean McCauliff
sumber
8
  • strictfp adalah pengubah yang membatasi perhitungan floating point sesuai IEEE 754.

  • Ini dapat digunakan pada seluruh kelas seperti "public strictfp class StrictFpModifierExample {}" atau pada metode "public strictfp void example ()". Jika digunakan di kelas maka semua metode akan mengikuti IEEE 754 dan jika digunakan pada metode maka metode tertentu akan ikuti IEEE 754.

  • Mengapa ini digunakan ?? ::: Karena platform yang berbeda memiliki perangkat keras floating point yang berbeda yang menghitung dengan lebih presisi dan rentang nilai yang lebih besar daripada spesifikasi java yang membutuhkan yang dapat menghasilkan output yang berbeda pada plateforms.s berbeda, maka itu mengkonfirmasi output yang sama terlepas dari perbedaan bentuk plat

  • strictfp juga memastikan untuk mengambil keuntungan dari kecepatan dan ketepatan operasi floating-point presisi yang diperluas.

  • Tidak ada kerugian dengan kata kunci ini yang bisa kita gunakan ketika kita melakukan perhitungan floating point

  • Poin terakhir saya adalah - Apakah IEEE754 secara singkat IEEE 754 mendefinisikan metode standar untuk perhitungan floating point dan penyimpanan nilai-nilai floating point baik tunggal (32-bit, digunakan dalam Java float) atau ganda (64-bit, digunakan di Jawa ganda) presisi. Ia juga mendefinisikan norma untuk perhitungan menengah dan untuk format presisi diperluas.

Rahul Saxena
sumber
2

strictfpadalah kata kunci dan dapat digunakan sebagai pengubah non-akses untuk kelas atau metode (tetapi tidak pernah variabel). Menandai kelas sebagai strictfpcara bahwa kode metode apa pun di kelas akan sesuai dengan aturan standar IEEE 754 untuk floating point.

Tanpa pengubah itu, floating point yang digunakan dalam metode mungkin berperilaku tergantung pada platform. Dengan itu Anda dapat memprediksi bagaimana floating point Anda akan bertindak terlepas dari platform yang mendasari JVM berjalan. Kelemahannya adalah bahwa jika platform yang mendasarinya mampu mendukung presisi yang lebih besar, suatu strictfpmetode tidak akan dapat memanfaatkannya.

Jika Anda tidak mendeklarasikan kelas sebagai strictfp, Anda masih bisa mendapatkan strictfpperilaku berdasarkan metode-demi-metode, dengan mendeklarasikan metode sebagai strictfp.

~ SCJP Sun® Programmer Bersertifikat untuk Java ™ 6 - Kathy Sierra & Bert Bates ~

Shanaka Jayalath
sumber
0

Mungkin di bawah ini contohnya membantu dalam memahami hal ini dengan lebih jelas: Di java kapan pun kita menggunakan mencari informasi yang tepat untuk operasi apa pun misalnya jika kita melakukan double num1 = 10e + 102; double num2 = 8e + 10; hasil = num1 + num2;

        The output will be so long and not precise, becasue it is precissed by the hardware e.g JVM and JIT has the license 
        as long as we dont have specify it Strictfp

Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same
One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to 
be deterministic no matter what the underlying hardware or CPU is.
Neeraj
sumber
0

Kata kunci 'strictfp' digunakan untuk memaksa ketepatan perhitungan floating point (float atau double) di Java sesuai dengan standar 754 IEEE, secara eksplisit. Jika Anda tidak menggunakan kata kunci strictfp, presisi floating point tergantung pada perangkat keras platform target.

Jika suatu antarmuka atau kelas dideklarasikan dengan strictfp, maka semua metode dan tipe bersarang di dalam antarmuka atau kelas tersebut secara implisit adalah strictfp.

Tautan referensi

Hari Krishna
sumber