Когда следует использовать ключевое слово "strictfp" в java?

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

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

Ответ 1

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

Из JLS:

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

Другими словами, это означает, что Write-Once-Run-Anywhere на самом деле означает Write-Once-Get-Equally-Wrong-Results-Everywhere.

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

Ответ 2

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

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

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

Ответ 3

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

  • Использование strictfp (JDC Tech Tip)
  • jGuru: Что такое модификатор strictfp? Когда я буду использовать его?

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

  • strictfp - Java Glossary

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

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

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

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

Ответ 4

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

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

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

Ответ 5

Как упоминалось в других ответах, результаты промежуточной с плавающей запятой соответствуют спецификации IEEE. В частности, процессоры x86 могут хранить промежуточные результаты с различной точностью по спецификации IEEE. Ситуация усложняется, когда JIT оптимизирует конкретный расчет; порядок, при котором инструкции могут отличаться друг от друга каждый раз, что приводит к слегка отличному округлению.

Накладные расходы, вызванные strictfp, вероятно, будут очень зависимыми от процессора и JIT. Эта статья в wikipedia на SSE2, похоже, имеет некоторое представление о проблеме. Поэтому, если JIT может генерировать инструкции SSE для выполнения вычисления, кажется, что strictfp не будет иметь накладных расходов.

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

Ответ 6

  • strictfp - это модификатор, который ограничивает вычисления с плавающей запятой в соответствии с IEEE 754.

  • Это можно использовать для всего класса, такого как "public strictfp class StrictFpModifierExample {}" или метода "public strictfp void example()". Если он используется в классе, то все методы будут следовать за IEEE 754 и, если они будут использоваться по методу, то конкретный метод будет следовать за IEEE 754.

  • Почему он используется??: Поскольку разные платформы имеют разные аппаратные средства с плавающей запятой, которые вычисляют с большей точностью и большим диапазоном значений, чем требуется спецификация java, которая может создавать различный вывод на разных пластинках. Так что он подтверждает тот же вывод независимо от разных форм пластин.

  • strictfp также обеспечивает возможность использования скорости и точности операций с плавающей запятой с расширенной точностью.

  • Нет недостатка в этом ключевом слове, который мы можем использовать, когда выполняем вычисления с плавающей запятой

  • Мой последний вопрос: что такое IEEE754? IEEE 754 определяет стандартный метод как для вычислений с плавающей запятой, так и для хранения значений с плавающей запятой в одиночной (32-разрядной, используемой в плаваниях Java) или двойной (64-разрядной, используемой в Java удваивается) точности. Он также определяет нормы для промежуточных вычислений и для расширенных форматов точности.

Ответ 7

strictfp - это ключевое слово и может использоваться как модификатор non-access для классов или методов (но никогда не переменных). Маркировка класса как strictfp означает, что любой код метода в классе будет соответствовать стандартным правилам IEEE 754 для плавающих точек.

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

Если вы не объявляете класс как strictfp, вы все равно можете получить поведение strictfp для метода по методу, объявив метод как strictfp.

~ SCJP Sun®Certified Programmer для Java ™ 6 - Кэти Сьерра и Берт Бейтс ~