Когда я должен использовать ключевое слово "strictfp" в java?
Я посмотрел, что это делает, но у кого-нибудь есть пример того, когда вы будете использовать strictfp
ключевое слово в Java? Кто-нибудь нашел применение этому?
будут ли какие-либо побочные эффекты просто положить его на все мои операции с плавающей запятой?
8 ответов
Strictfp гарантирует, что вы получите точно такие же результаты от ваших вычислений с плавающей запятой на каждой платформе. Если вы не используете strictfp, реализация JVM может использовать дополнительную точность там, где она доступна.
в пределах FP-строгого выражения, все промежуточные значения должны быть элементами значения float или double значение, подразумевая, что результаты из всех выражений FP-strict должны быть те предсказано арифметикой IEEE 754 на операндах, представленных с помощью single и двойные форматы. В выражение, которое не является FP-строгим, некоторые отсрочку предоставляется на реализации использовать расширенный диапазон экспонент для представления промежуточные результаты; чистый эффект, грубо говоря, это расчет может привести к " правильному ответ" в ситуациях, когда эксклюзив использование набора значений float или double набор значений может привести к переполнению или сгущенный продукт.
другими словами, речь идет о том, чтобы убедиться, что Write-Once-Run-Anywhere на самом деле означает Write-Once-Get-Equally-Wrong-Results-Everywhere.
с strictfp ваши результаты портативны, без него они более правоподобны для того чтобы быть точны.
Википедия На самом деле имеет хорошую статью об этой теме здесь, со ссылкой на спецификацию Java.
чтение между строк, подразумевается, что если вы не укажете strictfp
, тогда компилятор JVM и JIT имеет лицензию на вычисление ваших вычислений с плавающей запятой, как они хотят. В интересах скорости они, скорее всего, делегируют вычисления вашему процессору. С strictfp
on, вычисления должны соответствовать арифметике IEEE 754 стандарты, что на практике, вероятно, означает, что JVM будет выполнять вычисления.
Так почему вы хотите использовать strictfp
? Один из сценариев, который я вижу, находится в распределенном приложении (или многопользовательской игре), где все вычисления с плавающей запятой должны быть детерминированными независимо от базового оборудования или процессора. Какой компромисс? Скорее всего, время исполнения.
вот несколько ссылок:
- использование strictfp (Jdc Tech Tip)
-
jGuru: что модификатор strictfp для? Когда я смогу его использовать?
В основном, все сводится к тому, что вам все равно, что результаты выражений с плавающей запятой в вашем коде быстрые или предсказуемые. Например, если вам нужны ответы, которые предлагает ваш код, использующий плавающую точку значения должны быть согласованы на нескольких платформах, а затем использовать
strictfp
. -
оборудование с плавающей запятой вычисляет с большей точностью и с большим диапазоном значений, чем требует спецификация Java. Было бы странно, если бы некоторые платформы давали больше точности, чем другие. Когда вы используете
strictfp
модификатор на методе или классе компилятор генерирует код, который строго придерживается спецификация Java для идентичных результатов на всех платформах. Безstrictfp
, Он немного слабее, но не настолько слабый, чтобы использовать биты защиты в Pentium, чтобы дать 80 бит точности. -
и, наконец, фактическая спецификация языка Java,§15.4 FP-строгие выражения:
в выражении FP-strict все промежуточные значения должны быть элементами набора значений float или набора double, что означает, что результаты всех FP-строгих выражений должны быть предсказаны арифметикой IEEE 754 на операндах, представленных с использованием одиночного и двойного форматов. В выражении, которое не является строгим FP, предоставляется некоторая свобода действий для реализации для использования расширенного диапазона показателей для представления промежуточных результатов; чистый эффект, грубо говоря, заключается в том, что расчет может дать "правильный ответ" в ситуациях, когда исключительное использование набора значений float или набора двойных значений может привести к переполнению или сгущенный продукт.
Я никогда лично не использовал его, Хотя.
все началось с истории,
когда java разрабатывался Джеймсом Гослингом, Гербертом и остальной частью его команды. У них на уме была сумасшедшая штука под названием кроссплатформенности. Они хотели сделать дуб (Java) настолько лучше, что он будет работать точно так же на любой машине, имеющей другой набор инструкций, даже с различными операционными системами. Но была проблема с десятичными точками, также известными как плавающая точка и дважды в языках программирования. Некоторые машины были построены эффективность прицеливания в то время как остальные были точность прицеливания. Таким образом, более поздние(более точные) машины имели размер с плавающей запятой как 80 бит, в то время как первые(более эффективные/быстрые) машины имели 64-битные двойники. Но это было против основной идеи создания платформы независимого языка. Кроме того, это может привести к потере точности/данных, когда код построен на некоторой машине(имеющей двойной размер 64 бит) и запускается на другом виде машина (имеющ двойник размера 80 битов).
Up-Sizing можно допустить но Down-Sizing не может быть. Так они наткнулись на понятие strictfp, т. е. строгая плавающая точка. Если вы используете это ключевое слово с классом / функцией, то его плавающая точка и двойники имеют согласованный размер над любой машиной. т. е. 32/64 -бит соответственно.
Как упоминалось в других ответах, это приводит к тому, что промежуточные результаты с плавающей запятой соответствуют спецификации IEEE. В частности, процессоры x86 могут хранить промежуточные результаты с точностью, отличной от спецификации IEEE. Ситуация усложняется, когда JIT оптимизирует конкретное вычисление; порядок инструкций может быть различным каждый раз, что приводит к немного различному округлению.
издержки, понесенные strictfp может быть очень процессор и JIT зависимости. Эта статья Википедии на С SSE2 кажется, есть некоторое представление о проблеме. Поэтому, если JIT может генерировать инструкции SSE для выполнения вычисления, кажется, что strictfp не будет иметь никаких накладных расходов.
в моем текущем проекте есть несколько мест, где я использую strictfp. Существует точка, где потенциальные космические лучи должны быть удалены из значений пикселей. Если какой-то внешний исследователь имеет то же значение пикселя и космический луч перед ними, они должны получите такое же результирующее значение, как и наше программное обеспечение.
strictfp-это модификатор, который ограничивает вычисления с плавающей запятой в соответствии с IEEE 754.
Это можно использовать для всего класса, например "public strictfp class StrictFpModifierExample {}" или для метода " public strictfp void example ()".Если он используется в классе, то все методы будут следовать IEEE 754, а если используется в методе, то конкретный метод будет следовать IEEE 754.
почему он используется??::: Поскольку разные платформы имеют разные оборудование с плавающей запятой, которое вычисляет с большей точностью и большим диапазоном значений, чем требует спецификация java, которое может производить разный выход на разных платеформах.таким образом, он подтверждает один и тот же выход независимо от различных plateforms
strictfp также обеспечивает для того чтобы принять преимущество скорости и точности выдвинутых деятельностей с плавающей запятой точности.
нет недостатка в этом ключевом слове, которое мы можем использовать, когда мы делаем расчеты с плавающей запятой
мой последний момент-что такое IEEE754 вкратце Стандарт IEEE 754 определяет стандартный способ для вычислений с плавающей запятой и хранения значений с плавающей точкой, либо в одном (32-бит, используется в Java плавает) или Double (64-бит, используется в Java удваивается) точности.Он также определяет нормы для промежуточных вычислений и для расширенной точности форматы.
strictfp
является ключевым словом и может использоваться как модификатор без доступа для классов или методов (но никогда не переменных). Пометка класса как strictfp
означает, что любой код метода в классе будет соответствовать стандартным правилам IEEE 754 для плавающих точек.
без этого модификатора плавающие точки, используемые в методах, могут вести себя в зависимости от платформы. С его помощью вы можете предсказать, как ваши плавающие точки будут вести себя независимо от базовой платформы, на которой работает JVM. Недостатком является то, что если базовая платформа способна поддерживать высокую точность, а strictfp
метод не сможет воспользоваться ею.
если вы не объявляете класс как strictfp
, вы все еще можете сделать strictfp
поведение на основе метода по методу, объявив метод как strictfp
.
~ SCJP Sun®сертифицированный программист для Java™ 6-Kathy Sierra & Bert Bates ~
может ниже пример помочь в понимании этого более ясно : В java, когда мы используем поиск точной информации для любой операции, например если мы делаем двойное num1 = 10e+102; двойное num2 = 8e+10 ; результат = поля num1+ пит2
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.