Поводження з числами з плаваючою комою детерміновано
Плаваюча точка є детермінованою. Ну, так і має бути. Це складно.
Існує багато літератури про числа з плаваючою комою:
І наскільки вони проблемні:
Для реферату. Принаймні, на одному потоці ті самі операції з тими ж даними, що відбуваються в одному порядку, повинні бути детермінованими. Таким чином, ми можемо почати, турбуючись про введення та переупорядкування.
Одним із таких даних, що викликає проблеми, є час.
Перш за все, слід завжди обчислювати один і той же часовий крок. Я не кажу, щоб не вимірювати час, я кажу, що ви не витратите час на фізичне моделювання, тому що зміни часу є джерелом шуму в моделюванні.
Чому ви вимірюєте час, якщо не передаєте його на фізичне моделювання? Ви хочете виміряти минулий час, щоб знати, коли слід викликати крок моделювання, і - якщо ви використовуєте сон - скільки часу спати.
Таким чином:
- Час вимірювання: Так
- Використовуйте час для моделювання: Ні
Тепер переупорядкування інструкцій.
Компілятор міг би вирішити, що f * a + b
це те саме, що b + f * a
, однак, може мати інший результат. Він також може компілюватись до fmadd , або він може вирішити взяти кілька рядків, як це відбувається разом, і записати їх за допомогою SIMD , або якусь іншу оптимізацію, про яку я зараз не можу думати. І пам’ятайте, що ми хочемо, щоб одні й ті ж операції відбувалися в одному порядку, це стає причиною того, що ми хочемо контролювати, які операції відбуваються.
І ні, використання подвійного не врятує вас.
Вам потрібно потурбуватися про компілятор та його конфігурацію, зокрема для синхронізації чисел з плаваючою комою по всій мережі. Вам потрібно домогтися, щоб погодитись робити те саме.
Напевно, ідея складання була б ідеальною. Таким чином ви вирішите, яку операцію робити. Однак це може бути проблемою для підтримки декількох платформ.
Таким чином:
Справа для фіксованих точок чисел
Через те, як поплавці представлені в пам'яті, великі значення втрачають точність. Це стає причиною того, що збереження малих цінностей (затискач) пом'якшує проблему. Таким чином, немає величезних швидкостей і великих приміщень. Що також означає, що ви можете використовувати дискретні фізики, оскільки у вас менше ризику тунелювання.
З іншого боку, будуть накопичуватися невеликі помилки. Отже, усікайте. Я маю на увазі, масштабувати та додавати до цілого типу. Таким чином, ви знаєте, що нічого не створюється. Будуть операції, які ви можете виконати, залишившись з цілим типом. Коли вам потрібно повернутися до плаваючої точки, ви кидаєте та скасовуєте масштабування.
Примітка. Я кажу, що масштаб. Ідея полягає в тому, що 1 одиниця буде фактично представлена як потужність двох (наприклад, 16384). Як би там не було, зробіть це постійним і використовуйте. Ви в основному використовуєте його як номер фіксованої точки. Насправді, якщо ви можете використовувати правильні цифри з фіксованою точкою з якоїсь надійної бібліотеки набагато краще.
Я кажу, усікати. Щодо проблеми округлення, це означає, що ви не можете довіряти останній біт будь-якого значення, яке ви отримали після виступу. Отже, перед тим, як накинути шкалу, набрати трохи більше, ніж потрібно, і обрізати її згодом.
Таким чином:
- Тримайте значення малі: Так
- Ретельне округлення: так
- Коли можливі фіксовані номери точок: Так
Зачекайте, навіщо вам плаваюча точка? Не могли б ви працювати лише з цілим типом? О, так. Тригонометрія та радикація. Ви можете обчислити таблиці для тригонометрії та радикації та запекти їх у вашому джерелі. Або ви можете реалізувати алгоритми, що використовуються для обчислення їх з числом плаваючої крапки, за винятком використання цифр фіксованої точки. Так, вам потрібно збалансувати пам’ять, продуктивність та точність. Тим не менш, ви можете залишатися осторонь чисел з плаваючою комою та залишатися детермінованими.
Чи знаєте ви, що вони робили подібні речі для оригінальної PlayStation? Будь ласка , Meet My Dog, пластирі .
До речі, я не кажу не використовувати плаваючу крапку для графіки. Тільки для фізики. Я маю на увазі, звичайно, позиції будуть залежати від фізики. Однак, як відомо, коллайдер не повинен відповідати моделі. Ми не хочемо бачити результатів усічення моделей.
Таким чином: ВИКОРИСТУЙТЕ ФІКСОВАНІ БОЧКИ.
Щоб було зрозуміло, якщо ви можете використовувати компілятор, який дозволяє вам вказати, як працює плаваючі точки, і цього вам достатньо, то ви можете це зробити. Це не завжди варіант. Крім того, ми робимо це для детермінізму. Фіксовані точки не означають, що помилок немає, адже вони мають обмежену точність.
Я не думаю, що "фіксований номер важкий" - це вагомий привід не використовувати їх. І якщо ви хочете поважно використовувати їх, це детермінізм, зокрема детермінізм у різних платформах.
Дивитися також:
Додаток : Я пропоную зробити розмір світу невеликим. З огляду на це, обидва OP та Jibb Smart доводить до того, що віддалення від похідних поплавців має меншу точність. Це матиме вплив на фізику, таку, яку побачать набагато раніше, ніж край світу. Цифри з фіксованими точками, ну, мають фіксовану точність, вони будуть однаково хорошими (або поганими, якщо вам зручніше) скрізь. Що добре, якщо ми хочемо детермінізму. Я також хочу зазначити, що те, як ми зазвичай займаємось фізикою, має властивість посилювати невеликі варіації. Дивіться Ефект Метелика - Детермінована фізика в неймовірному виробнику машин та видобутку .
Ще один спосіб займатися фізикою
Я думав, що причина невеликих помилок у точності в числах з плаваючою точкою посилюється в тому, що ми робимо ітерації на цих числах. На кожному етапі моделювання ми беремо результати останнього кроку моделювання та робимо їх на роботі. Накопичення помилок на вершині помилок. Це ваш ефект метелика.
Я не думаю, що ми побачимо одну збірку, використовуючи одну нитку на одній машині, даючи різний вихід на одному вході. Однак на іншому верстаті це могло, або інша збірка могла.
Там є аргумент для тестування. Якщо ми вирішимо, як саме повинні працювати, і ми можемо протестувати на цільовому обладнання, ми не повинні розміщувати конструкції з іншою поведінкою.
Однак є також аргумент щодо того, щоб не працювати вдалині, що накопичує стільки помилок. Можливо, це можливість займатися фізикою по-іншому.
Як ви можете знати, існує неперервна і дискретна фізика, обидві працюють над тим, скільки б кожен об'єкт просунувся на часовий крок. Однак безперервна фізика має засоби з'ясувати момент зіткнення замість того, щоб перевірити різні можливі моменти, щоб побачити, чи сталося зіткнення.
Таким чином, я пропоную наступне: використовуйте методи безперервної фізики, щоб з'ясувати, коли відбудеться наступне зіткнення кожного об'єкта, з великим часовим кроком, набагато більшим за крок одного моделювання. Тоді ви берете найближчий момент зіткнення і з'ясовуєте, де все буде в цей момент.
Так, це велика робота одного кроку моделювання. Це означає, що моделювання не почнеться миттєво ...
... Однак ви можете імітувати наступні кілька кроків моделювання, не перевіряючи зіткнення кожен раз, тому що ви вже знаєте, коли відбудеться наступне зіткнення (або що у великому часовому кроці не відбувається зіткнення). Крім того, помилки, накопичені в цьому моделюванні, не мають значення, оскільки, як тільки моделювання досягає великого часового кроку, ми просто розміщуємо попередньо обчислені позиції.
Тепер ми можемо використовувати часовий бюджет, який ми використовували б для перевірки на зіткнення кожного кроку моделювання для обчислення наступного зіткнення після знайденого. Тобто ми можемо імітувати вперед, використовуючи великий часовий крок. Якщо припустити, що у світі обмежений обсяг (це не спрацює для величезних ігор), для моделювання повинна бути черга майбутніх станів, а потім кожен кадр, який ви просто інтерполюєте з останнього стану в наступний.
Я б заперечував за інтерполяцію. Однак, враховуючи, що є прискорення, ми не можемо просто інтерполювати все так само. Натомість нам потрібно інтерполювати з урахуванням прискорення кожного об'єкта. З цього питання ми можемо просто оновити позицію так само, як ми робимо для великого часового кроку (що також означає, що вона менш схильна до помилок, оскільки ми б не використовували дві різні реалізації для одного руху).
Примітка . Якщо ми робимо ці числа з плаваючою комою, такий підхід не вирішує проблему, коли предмети поводяться інакше, чим далі від походження. Однак, хоча це правда, що точність втрачається, чим далі ви йдете від походження, це все-таки детерміновано. Насправді, тому навіть не спочатку це підняли.
Додаток
Від ОП у коментарі :
Ідея полягає в тому, що гравці зможуть зберегти свої машини в якомусь форматі (наприклад, xml або json), щоб записати положення та обертання кожної деталі. Цей XML або json файл буде використаний для відтворення машини на комп'ютері іншого гравця.
Отже, жодного бінарного формату, правда? Це означає, що ми також повинні турбуватися, незалежно від відновлення чисел з плаваючою точкою, що відповідають оригіналу. Див.: Поточна точність переглянута: Переносимість дев'ятизначного поплавця