Про точність плаваючої точки і чому ми все ще використовуємо її


38

Плаваюча точка завжди була клопіткою для точності у великих світах.

Ця стаття пояснює закулісність та пропонує очевидну альтернативу - фіксовані точки. Деякі факти справді вражають, як-от:

"Добре 64 біт точності приводить вас до найдальшої відстані Плутона від Сонця (7,4 млрд км) з субмікрометровою точністю".

Точність субмікрометрової точності більше, ніж будь-яка потреба в fps (для позицій і навіть швидкостей), і це дозволить вам будувати дійсно великі світи.

Моє запитання: чому ми все ще використовуємо плаваючу крапку, якщо фіксована точка має такі переваги? Більшість API-рендерингу та бібліотеки фізики використовують плаваючу крапку (і страждають від її недоліків, тому розробникам потрібно їх обійти).

Вони настільки повільніші?

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


3
Останній "додатковий" біт, мабуть, повинен бути окремим питанням, тому основний не перебирає сторону.
Тетрад

Я хочу розібратися, як змусити фіксовану точку ... У моїй грі є всілякі дивні помилки, оскільки Lua також використовує FPU, і DirectX перетворюється на FPU ... Я бачив такі речі, як 2 * 9000 = 17995 або 500 * 10 = 4897 це справді нерозумно. Але найгірша помилка, мабуть, є тим, що обговорюється на форумах Ogre3D, де 1 + 5 = 4.
швидкість

3
Не виправдав коментар; але якщо ви вирішили використовувати фіксовану точку Q-Floats ( en.wikipedia.org/wiki/Q_(number_format) ) - ваш друг; вони смішно швидкі та легкі у виконанні.
Джонатан Дікінсон

Отже, підводячи підсумки ¿чи слід дотримуватися плаваючих точок (якщо я працюю в Java чи Python)? - Gastón 26 хвилин тому
Gastón

Відповіді:


20

Якщо ви дозволите мені безсоромний штекер, я наведу вам приклад із реальної гри, над якою працюю (відеопосилання YouTube).

У грі є нескінченний, процедурно створений світ на двигуні фізики. Тут використовується плаваюча точка з одноточною точністю. Після кількох сотень метрів ігрового простору починають виникати проблеми з точністю (і ставати прогресивніше гірше, чим далі ви отримаєте походження).

Моє рішення? Кожні 200 м або близько того я рухаю весь світ назад на 200 м у бік походження (якщо ви хочете знайти та спробувати один із прототипів на своєму веб-сайті та підняти накладку [w] orld на налагодження, ви можете це бачити).

Чому б не використовувати фіксовану точку? Або подвійна точність? Замість одноточної? Тому що все інше використовує єдину точну плаваючу точку!

Фізичний двигун, який я використовую, використовує його, XNA використовує його, дані, які завантажуються на відеокарту, форматуються як плаваюча точка з одноточною точністю. Навіть сама мова створена для роботи з числами з плаваючою комою - писати та (що важливіше) читання 0.5fнабагато простіше, ніж 0x80000000L.

Це просто питання того, що простіше на практиці. І чіткий переможець усвідомлює проблеми точності з плаваючою комою та пише досить прості функції "переміщення світу-назад до нуля" (або впровадження розділення простору або все, що підходить для вашої гри).

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


Мені завжди було цікаво, чи може легше деякі програми переміщувати все інше і тримати "програвача" на початку. Цікаво побачити, що я не єдиний!
Даш-Том-Банг

Мені подобаються ваші міркування. Я хотів би лише зазначити, що якщо мова йде про ігри, які передбачають мережеву фіксовану точку, то, здається, є менше примх / відхилень (прогнозування клієнта більш точне).
Джонатан Дікінсон

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

@jokoon Я вважав, що моя відповідь була цілком зрозумілою. Що стосується того, чому фіксована точка не впроваджена скрізь? Подивіться лише у Вікіпедію: "Дуже мало комп'ютерних мов включає вбудовану підтримку фіксованих значень, тому що для більшості додатків двійкові чи десяткові подання з плаваючою комою зазвичай простіші у використанні та досить точні ". Хороший дизайнер знає, що потрібно опустити - і те, що дублює функціональність таким чином, що програмісту дійсно легко стріляти в ногу, є хорошим кандидатом.
Ендрю Рассел

Домовились. Сьогоднішні процесори виконують інструкції з плаваючою комою дуже легко, інструкції мають відмінну пропускну здатність, і більшість є лише на кілька циклів довше затримки, ніж цілі інструкції.
doug65536

11

По-перше - так, вони значно швидші. Навіть якщо ви можете отримати фіксовану точку так само швидко, як "звичайний" FPU, реальна плаваюча точка має такі вигідні вказівки, як fsel для припинення розгалуження або SIMD для роботи на багатьох поплавках одночасно. GPU також використовують плаваючу крапку, принаймні в інтерфейсах, орієнтованих на користувачів.

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


5

Ще один важливий момент, який слід зробити, - це те, що поплавці не такі неточні, як здається, люди тут думають. 32-бітний поплавок має 24-бітну повну цільну точність. Це означає, що воно є принаймні настільки ж точним, як 24-бітове значення фіксованої точки для будь-якого заданого діапазону. У той час як поплавці стають менш точними, чим більше стає значення, значення фіксованої точки просто переповнюватиметься і обертатиметься в якийсь момент. Зменшення точності є кращим резервом. Поплавки також можуть переповнюватися, але далеко, далеко пізніше. Я хотів би бачити ваші обличчя, коли ваш світ раптом загортається до -2 ^ 31 через переповнення фіксованої точки.

64-бітні значення з плаваючою точкою мають 53-бітову цілісну точність, тому вони справді точні.


Значення з плаваючою комою насправді не переповнюються; якщо результат обчислення занадто великий за величиною, щоб бути представленим, то результат є нескінченним позитивним чи негативним.
Ананас

3

У контексті FPS значення фіксованої точки фактично можуть бути відповідальністю. Близька до нуля плаваюча точка є точнішою. Лише на великих відстанях фіксована точка стає більш кращою. Відповідь просто в тому, що це залежить від контексту.

Щось на зразок галактики ви можете використовувати системи відліку. Використовуйте величезну шкалу для сонячних систем, а потім використовуйте центр Сонця (або подібну точку) як точку походження для будь-якого всередині системи. Використовуючи цю систему, ви можете мати свій торт і з'їсти його, так би мовити, і його не важко передбачити.

IIRC, розробник Infinity заявив, що в одному зі своїх інтерв'ю він постійно повторювався навколо масштабних питань.


Навряд чи в будь-якій грі вам знадобиться «близька до нуля» точність з плаваючою точкою. Якщо у вас є одиничний метр, 10 біт точності надає субміліметрову точність і все ще дозволяє моделювати понад 4000 км у кожному напрямку, якщо ви застрягли з 32-бітовими значеннями. Якщо вам потрібна більша точність, ніж міліметр, тоді ви можете перенести ще кілька біт точно. Переміщення до 64 бітових значень у космічній грі дасть вам сонячну систему (або більше?) З постійною точністю протягом усього обсягу.
dash-tom-bang

Справді. І саме тому ви б використовували Сонце Сонячної системи як орієнтир у світі розмірів галактики! Справа в тому, що обраний вами метод поводження з точністю не приносить нічого до столу в будь-якому випадку. Це суперечка, тому ви можете також використовувати той, до якого налаштована ваша бібліотека / обладнання.
Rushyo

Я, до речі, працював над грою, де нам довелося моделювати понад 4000 км у кожному напрямку. Для сумісності з кодом в інших проектах довелося використовувати 32 біти для позицій. Це не теоретична проблема, враховуючи комерційні вимоги до повторного використання коду та розмір ігрових світів сьогодні.

1

Якщо ви ще цього не зробили, вам слід остаточно ознайомитись з навчальним посібником з виведення планет на GameDev.net. Що стосується розподілу простору, одне рішення - зберегти дві окремі змінні положення - одну макромасштаб та одну мікро шкалу. Це працює досить добре (перевірено).

Точне рішення залежить від того, як ви плануєте обробляти екстремальні відстані в двигуні - чи плануєте ви стрибкові ворота чи стиснення часу?


1

Однією з причин є те, що арифметика з плаваючою комою є "досить хорошою" (або, принаймні, це було), вона швидко дає досить точні результати.

Поки ви знаєте про обмеження арифметики з плаваючою комою та зміните свої алгоритми, щоб впоратися з ними (див. Відповідь Ендрю Рассела), тоді ви створите код, який "працює".


-1

Я пишу гру. У своїй грі / програмі я малюю космічний корабель на початку, використовуючи досить фіксовану камеру, а свою планету малюю за допомогою окремої камери. І ці дві речі вирішують цю проблему для мене, але моя планета ще не дуже детальна. Що стосується рішення, яке Ендрю Рассел згадував про переміщення світу (і я припускаю, що камера та її мешканці повернулися до походження), я дійсно не намагався би цього зробити, якщо ви коли-небудь плануєте зробити цю гру мережевою грою. Якщо ви перенесли світ на серверній програмі на основі кожного руху клієнтів, то світ врешті-решт бореться за позицію. І займав би свою позицію весь час від усіх, хто грав, що було б величезним збоєм.

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