Коли я повинен використовувати ключове слово "strictfp" у Java?


258

Я роздивився, що це робить, але чи справді хтось має приклад, коли ви використовували strictfpключове слово на Java? Хтось насправді знайшов для цього застосування?

Чи будуть якісь побічні ефекти просто нанести це на всі мої операції з плаваючою точкою?


1
Завжди, якщо вам справді не потрібна продуктивність більше, ніж потрібно відтворюваність.
Сурма

1
@Антиман - або точність / правильність. Наприклад, x86 / x64 використовують 80-бітні регістри з плаваючою точкою всередині, тому результат буде більш точним для тривалого обчислення без строгості.
Роберт Фрейзер

1
@Robert Власне, специфікація гарантує обмежену точність мантіси. Єдина відмінність полягає в тому, що він може використовувати більшу точність показника, ніж звичайна, що має різниці в рідкісних випадках через подвійне округлення.
Сурма

Я думаю, що на додаток до можливості розповсюдження цього корисного модифікатора по всьому суглобу, новою sfloat & sdouble примітивними жорсткими типами datafp може стати гарною ідеєю.
TheRiley

Відповіді:


274

Strictfp гарантує, що ви отримаєте абсолютно однакові результати від розрахунків з плаваючою комою на кожній платформі. Якщо ви не використовуєте строгий Fp, реалізація JVM може використовувати додаткову точність, коли це можливо.

Від JLS :

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

Іншими словами, мова йде про те, щоб переконатися, що Write-Once-Run-Anywhere означає насправді Write-Once-Get-Equally-Wrong-Results-Everywhere .

Завдяки строгому файлу ваші результати є портативними, без цього вони швидше будуть точними.


28
Використовуйте його для відтворюваних наукових результатів та тестових одиничних розрядів.
Олександр Дубінський

1
"Якщо ви не використовуєте строгий Fp, реалізація JVM може використовувати додаткову точність, коли це можливо", - це звучить як погана річ: P
AMDG

@LinkTheProgrammer це, безумовно, може бути поганою справою
Тим

@TimCastelijns Я вважаю, що Happy Wheels - це ваша довідка? Повторення записів натискань клавіш; завдяки різноманітності точності реалізації FP-математики, повтори точні лише на аналогічному обладнанні. Чи можете ви назвати більш реалістичну проблему, викликану змінною математикою з плаваючою комою? Я можу уявити, можливо, симулятор частинок, але що ще?
AMDG

Отже, це означає, що ми завжди мусимо використовувати strogfp у виробництві, де задіяно кілька платформ?
beatrice

65

Вікіпедія насправді має хорошу статтю про цю тему тут із посиланням на специфікацію Java.

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

То чому б ви хотіли використовувати strictfp? Я можу побачити один із розроблених програм (або багатокористувацької гри), де всі обчислення з плаваючою комою повинні бути детермінованими, незалежно від того, що є базовим обладнанням чи процесором. Що таке компроміс? Швидше за все час виконання.


5
"Розширений діапазон експонентів для представлення проміжних результатів" не є "ліцензією на обчислення ваших обчислень з плаваючою комою, як би вони не хотіли", а на практиці навіть для strictfpобчислень використовується навіть непомітний FPU 8087. І лише тоді потрібно доглядати трохи. Див stackoverflow.com/questions/18496560 / ...
Pascal Cuoq

Я погоджуюся з @PascalCuoq re: "ліцензія на обчислення ваших обчислень з плаваючою комою, хоч вони хочуть" . Якщо ні, то, здається, у цьому випадку все навпаки, оскільки strictfpзабезпечує відповідність стандарту IEEE 754 (так що ви отримаєте однаковий результат на всіх платформах). Єдиний недолік, який я можу бачити, - це те, що ви можете втратити переваги наявності справжнього FPU у вашому рідному обладнання.
друкарка

25

Все почалося з історії,

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

Підвищення розміру можна допустити, але зменшення розміру не може бути. Отже, вони натрапили на концепцію Strostfp, тобто сувора плаваюча точка . Якщо ви використовуєте це ключове слово з класом / функцією, то його плаваюча точка і подвійні розміри мають стійкий розмір для будь-якої машини. тобто 32/64-біт відповідно.


8
У Java 1.2 було введено Strogfp. Це було набагато пізніше, ніж тоді, коли проектували дуб.
Thorbjørn Ravn Andersen

"цифри десяткової крапки, також відомі як плаваюча точка" - Десяткові означає базу 10 і не мають нічого спільного з поданнями з плаваючою комою.
aioobe

21

Ось кілька посилань:

  • Використовуючи строгий Fp (технічна порада JDC)
  • jGuru: Для чого призначений модифікатор строгого файлу? Коли я б розглядав можливість його використання?

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

  • strictfp - Словник Java

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

  • І нарешті, власне специфікація мови Java, §15.4 FP-строгі вирази :

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

Я ніколи особисто не використовував це для цього.


12

Як згадували інші відповіді, це призводить до того, що результати проміжних плаваючих точок відповідають специфікації IEEE. Зокрема процесори x86 можуть зберігати проміжні результати з різною точністю від специфікації IEEE. Ситуація ускладнюється, коли JIT оптимізує конкретні обчислення; Інструкції щодо порядку можуть бути різними щоразу, що призводить до дещо різного округлення.

Накладні витрати, понесені строгим файлом, можуть бути дуже залежні від процесора та JIT. Ця стаття у Вікіпедії про SSE2, здається, має деяке розуміння проблеми. Отже, якщо JIT може генерувати інструкції SSE для виконання обчислення, то, здається, що строковий Fp не матиме накладних витрат.

У моєму теперішньому проекті є кілька місць, де я використовую строгий файл. Є момент, коли потенційні космічні промені потрібно видалити зі значень пікселів. Якщо якийсь зовнішній дослідник має те саме значення пікселя та космічний промінь перед ними, вони повинні отримати те саме значення, що й наше програмне забезпечення.


8
  • strictfp - це модифікатор, який обмежує обчислення з плаваючою точкою згідно IEEE 754.

  • Це може бути використано для цілого класу, наприклад, "public strictfp class StrictFpModifierExample {}" або для методу "public strictfp void example ()". Якщо він використовується в класі, ніж усі методи будуть слідувати IEEE 754, а якщо використовується в методі, то конкретний метод буде дотримуйтесь IEEE 754.

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

  • strifp також гарантує скористатися швидкістю та точністю розширених операцій з плаваючою точкою.

  • Немає недоліків у цьому ключовому слові, яке ми можемо використовувати, коли робимо обчислення з плаваючою комою

  • Останнє моє значення - Що таке IEEE754, коротше IEEE 754 визначає стандартний метод як для обчислень з плаваючою комою, так і для зберігання значень з плаваючою точкою або в одиночному (32-розрядний, що використовується в плавках Java), або подвійному (64-розрядний, використовується в Java удвічі) точність. Він також визначає норми для проміжних обчислень та для розширених форматів точності.


2

strictfpє ключовим словом і може використовуватися як модифікатор без доступу для класів або методів (але ніколи не змінних). Позначення класу strictfpозначає, що будь-який код методу в класі відповідатиме стандартним правилам IEEE 754 для плаваючих точок.

Без цього модифікатора плаваючі точки, що використовуються в методах, можуть поводитись залежно від платформи. З його допомогою ви можете передбачити, як будуть поводитися ваші плаваючі точки незалежно від базової платформи, на якій працює JVM. Мінус полягає в тому, що якщо базова платформа здатна підтримувати більшу точність, strictfpметод не зможе нею скористатися.

Якщо ви не оголосите клас як strictfp, ви все одно можете отримати strictfpповедінку методом за методом, оголосивши метод як strictfp.

~ SCJP Sun®Сертифікований програміст для Java ™ 6 - Kathy Sierra & Bert Bates ~


0

Нижче наведений приклад може допомогти зрозуміти це більш зрозуміло: у Java, коли ми використовуємо шукати точну інформацію для будь-якої операції, наприклад, якщо ми робимо подвійне число1 = 10е + 102; подвійне число2 = 8е + 10; результат = 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.

0

Ключове слово 'strictfp' використовується для примусової точності обчислень з плаваючою комою (поплавком або подвійним) у Java, явно відповідає стандарту 754 IEEE. Якщо ви не використовуєте ключове слово Stroffp, точність з плаваючою комою залежить від обладнання обладнання цільової платформи.

Якщо інтерфейс або клас оголошено строгим файлом, то всі методи і вкладені типи в цьому інтерфейсі або класі явно строгі.

Посилання на посилання

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.