Вопрос-ответ

When should I use the "strictfp" keyword in java?

Когда я должен использовать ключевое слово "strictfp" в Java?

Я посмотрел, что это делает, но есть ли у кого-нибудь пример того, когда вы могли бы использовать strictfp ключевое слово в Java? Кто-нибудь действительно нашел применение для этого?

Будут ли какие-либо побочные эффекты от простого использования его во всех моих операциях с плавающей запятой?

Переведено автоматически
Ответ 1

Strictfp гарантирует, что вы получите точно такие же результаты от ваших вычислений с плавающей запятой на каждой платформе. Если вы не используете strictfp, реализация JVM может свободно использовать дополнительную точность, где это возможно.

Из JLS:


В выражении FP-strict все промежуточные значения должны быть элементами набора значений с плавающей запятой или набора значений double, подразумевая, что результаты всех выражений FP-strict должны соответствовать результатам, предсказанным арифметикой IEEE 754 для операндов, представленных в одинарном и двойном форматах. В выражении, которое не является FP-строгим, реализации предоставляется некоторая свобода действий для использования расширенного диапазона экспонент для представления промежуточных результатов; конечный эффект, грубо говоря, заключается в том, что вычисление может дать "правильный ответ" в ситуациях, когда исключительное использование набора значений с плавающей запятой или двойного набора значений может привести к переполнению или недостаточному потоку.


Другими словами, речь идет о том, чтобы убедиться, что запись-один раз-запуск-везде на самом деле означает Запись-Один раз-Получение-Одинаково-неправильных-результатов-везде.

С strictfp ваши результаты переносимы, без него они, скорее всего, будут точными.

Ответ 2

На самом деле, есть хорошая статья в Википедии о strictfp со ссылкой на раздел спецификации Java о типах, форматах и значениях с плавающей запятой.

Читая между строк, подразумевается, что если вы не укажете strictfp, то JVM и JIT-компилятор имеют лицензию на выполнение ваших вычислений с плавающей запятой так, как они хотят. В интересах скорости они, скорее всего, делегируют вычисления вашему процессору. При strictfp вкл вычисления должны соответствовать стандартам арифметики IEEE 754, что на практике, вероятно, означает, что вычисления будет выполнять JVM.

Итак, почему вы хотели бы использовать strictfp? Один из сценариев, который я вижу, касается распределенного приложения (или многопользовательской игры), где все вычисления с плавающей запятой должны быть детерминированными, независимо от базового оборудования или процессора. Каков компромисс? Наиболее вероятное время выполнения.

Ответ 3

Обновление Java 17

strictfp имел такой узкий набор вариантов использования, что начиная с Java 17, его функциональность была удалена. Это все еще допустимый модификатор, но теперь strictfp ничего не делает (исходный код JLS).

Вместо этого все операции с плавающей запятой теперь являются строгими, как это было до того, как strictfp был представлен в Java 1.2. На современных процессорах больше нет никаких дополнительных затрат на производительность.


Оригинальный ответ

Вот несколько ссылок:


  • Использование strictfp (технический совет JDC)



  • jGuru: Для чего нужен модификатор strictfp? Когда я мог бы рассмотреть его использование?



    По сути, все это сводится к тому, заботитесь ли вы о том, чтобы результаты выражений с плавающей запятой в вашем коде были быстрыми или предсказуемыми. Например, если вам нужны ответы, которые выдает ваш код, который использует значения с плавающей запятой для обеспечения согласованности на нескольких платформах, тогда используйте strictfp.




  • strictfp - Глоссарий Java



    Аппаратное обеспечение с плавающей запятой вычисляет с большей точностью и с большим диапазоном значений, чем требуется спецификацией Java. Было бы запутанно, если бы некоторые платформы давали большую точность, чем другие. Когда вы используете модификатор strictfp для метода или класса, компилятор генерирует код, который строго соответствует спецификации Java для получения идентичных результатов на всех платформах. Без strictfp, это немного мягче, но не настолько, чтобы использовать защитные биты в Pentium для обеспечения точности 80 бит.




  • И, наконец, фактическая спецификация языка Java, § 15.4 FP-строгие выражения:



    В выражении FP-strict все промежуточные значения должны быть элементами набора значений с плавающей запятой или набора значений double, подразумевая, что результаты всех выражений FP-strict должны соответствовать результатам, предсказанным арифметикой IEEE 754 для операндов, представленных в одинарном и двойном форматах. В выражении, которое не является FP-строгим, реализации предоставляется некоторая свобода действий для использования расширенного диапазона экспонент для представления промежуточных результатов; конечный эффект, грубо говоря, заключается в том, что вычисление может дать "правильный ответ" в ситуациях, когда исключительное использование набора значений с плавающей запятой или двойного набора значений может привести к переполнению или недостаточному потоку.




Однако лично я никогда им не пользовался.

Ответ 4

Все началось с истории,

Когда java разрабатывали Джеймс Гослинг, Герберт и остальные члены его команды. У них была эта сумасшедшая идея под названием независимость от платформы. Они хотели сделать oak (Java) настолько лучше, чтобы он работал точно так же на любой машине с другим набором команд, даже под управлением разных операционных систем. Но возникла проблема с десятичными числами, также известными как числа с плавающей запятой и double в языках программирования. Некоторые машины были созданы с целью повышения эффективности, в то время как остальные были нацелены на точность. Итак, более поздние (более точные) машины имели размер с плавающей запятой в 80 бит, в то время как первые (более эффективные / быстрые) машины имели 64-битные удвоения. Но это противоречило основной идее создания языка, независимого от платформы. Кроме того, это может привести к потере точности / данных, когда код создается на некоторой машине (с двойным размером 64 бита) и запускается на другой машине (с двойным размером 80 бит).

Увеличение размера допустимо, но уменьшение - нет. Итак, они наткнулись на концепцию strictfp, т.е. строгую плавающую точку. Если вы используете это ключевое слово с классом / функцией, то его размер с плавающей запятой и удвоения будут одинаковыми на любой машине. т. е. 32/64 -разрядными соответственно.

java