浮動小数点の精度と、なぜそれを使用するのか


38

浮動小数点は、大きな世界での正確さのために常に面倒でした。

この記事では、舞台裏について説明し、明らかな代替手段である固定小数点数を提供します。次のようないくつかの事実は本当に印象的です:

「64ビットの精度で、太陽からPl王星までの最も遠い距離(74億km)にサブマイクロメートルの精度で到達できます。」

サブマイクロメートルの精度は、fpsが必要とする(位置や速度でさえ)必要以上のものであり、本当に大きな世界を構築することができます。

私の質問は、固定小数点にそのような利点があるのに、なぜ浮動小数点を使用するのですか?ほとんどのレンダリングAPIと物理ライブラリは浮動小数点を使用します(そして、その欠点に苦しむため、開発者はそれらを回避する必要があります)。

彼らはとても遅いですか?

また、アウターラやインフィニティなどのスケーラブルな惑星エンジンは、大規模をどのように処理すると思いますか?位置に固定小数点を使用していますか、それとも空間分割アルゴリズムがありますか?


3
最後の「追加の」ビットは、おそらく別の質問である必要がありますので、メインの質問は脇道になりません。
Tetrad

固定小数点を強制する方法を考えたい... LuaはFPUを使用しているため、ゲームにはあらゆる種類の奇妙なエラーがあり、DirectXはFPUともフィドルしています... 2 * 9000 = 17995または500 * 10のようなものを見ました= 4897それは本当にばかげています。しかし、最悪のエラーはおそらく= 4.1 + 5 Ogre3Dフォーラムで議論されたもの、である
スピーダー

3
コメントを正当化しませんでした。しかし、固定小数点Q-Floats(en.wikipedia.org/wiki/Q_ ( number_format))を使用することに決めた場合はあなたの友達です。それらは途方もなく高速で実装が簡単です。
ジョナサンディキンソン

要約すると、¿(浮動小数点を使用する必要があります(JavaまたはPythonで作業している場合))–ガストン26分前
ガストン

回答:


20

恥知らずなプラグインを許可してくれるなら、私が取り組んでいる実際のゲームの例を紹介します(YouTubeビデオリンク)。

このゲームには、物理​​エンジン上に無限に手続き的に生成された世界があります。単精度浮動小数点を使用します。数百メートルのゲーム空間の後、精度の問題が発生し始めます(そして、あなたが得る起源から遠ざかるにつれて次第に悪化します)。

私の解決策は?200mごとに、世界全体を200mずつ原点に向かって移動します(私のサイトでプロトタイプの1つを見つけて試してみて、[w] orldデバッグオーバーレイを表示すると、このことがわかります)。

なぜ固定小数点を使用しないのですか?または倍精度?単精度の代わりに?他のすべてが単精度浮動小数点を使用しているためです

私が使用している物理エンジンはそれを使用し、XNAはそれを使用し、グラフィックカードにロードされるデータは単精度浮動小数点としてフォーマットされます。言語自体でさえ、浮動小数点数で動作するように設計されています-書き込みと(より重要なこと0.5fですが)読み取りははるかに簡単0x80000000Lです

それは単に実際に簡単なことの問題です。そして、明確な勝者は小数点精度の問題を浮きを意識している書き込みかなり単純な「移動-世界のバック・ツー・ゼロ」の機能(または空間分割または任意のあなたのゲームに合っを実装します)。

そして最後に別の例-Orbiterはゲーム(シミュレーション)であり、精度を重視する必要があります。宇宙空間だけでなく、時間的にも(時間加速に加えて軌道を回っている物体-空から落下したくないようになりました)。また、浮動小数点数を使用し、安定性を維持するためにハック採用しています。


一部のアプリケーションでは、他のすべてを移動して「プレーヤー」を原点に保持する方が簡単かどうかはいつも疑問でした。面白いのは私だけではない!
ダッシュトムバン

あなたの推論が好きです。固定小数点のネットワーキングを含むゲームに関しては、癖/偏差が少ないようです(クライアントの予測はより正確です)。
ジョナサンディキンソン

私はあなたの議論をあまりよく理解していません。ところで、なぜ言語はまだ固定小数点を実装していないのですか?もちろん、それがフロートを使用するように描かれる理由のようですが、それは固定小数点がどこでも実装されていない理由を説明しません。
jokoon

@jokoon私の答えは非常に明確だと思いました。なぜ固定小数点がどこにも実装されていないのか?ウィキペディアを見てください:「ほとんどのアプリケーションでは、バイナリまたは10進の浮動小数点表現は通常、使いやすく、十分に正確なので、固定小数点値のサポートが組み込まれているコンピューター言語はほとんどありませ。」優れたデザイナーは、何を省くべきかを知っています。プログラマーが自分の足で簡単に自分自身を撃つことができるように機能を複製するものは、良い候補です。
アンドリューラッセル

同意した。今日のプロセッサは浮動小数点命令を非常に簡単に実行します。命令は優れたスループットを持ち、ほとんどは整数命令よりも数サイクル長いレイテンシーです。
-doug65536

11

まず-はい、それらは非常に高速です。「通常の」FPUと同じ速さで固定小数点を使用できる場合でも、実際の浮動小数点には、分岐を停止するfselや、一度に多くの浮動小数点で動作するSIMDなどの有利な命令があります。GPUは、少なくともユーザー向けのインターフェイスでは、浮動小数点も使用します。

第二に、64ビットは浮動小数点でもかなり遠くまで到達します-ほとんどの人はまだ32を使用しますが、主な利点はそれがスケーリングされることです。その固定小数点スケールの精度は固定されています。uto王星への太陽の測定でも、通りの向こう側でも、同じ精度を得ることができます。関係するすべての値が小さい場合、浮動小数点はより正確な結果を提供します。一般的な物理ライブラリは、さまざまなスケールの多くのゲームで少なくとも無難に動作することが期待されているため(一部のゲーム自体はスケールが大きく異なる場合があります)、多くのスケールで動作する種類の数字を使用する必要があります。


5

もう1つの重要な点は、フロートは不正確ではないということです。32ビットのfloatには、24ビットの完全な整数精度があります。これは、任意の範囲で少なくとも24ビットの固定小数点値と同じくらい正確であることを意味します。値が大きくなるとフロートの精度は低下しますが、固定小数点値は単純にオーバーフローし、ある時点で折り返されます。精度を下げると、より適切なフォールバックになります。フロートもオーバーフローする可能性がありますが、はるかに遅くなります。固定小数点のオーバーフローのために、あなたの世界が突然-2 ^ 31にラップアラウンドしたとき、あなたの顔を見たいです。

64ビットの浮動小数点値は53ビットの整数精度を持っているため、本当に正確です。


浮動小数点値は実際にはオーバーフローしません。計算の結果が大きすぎて表現できない場合、結果は正または負の無限大になります。
パイナップル

3

FPSのコンテキストでは、固定小数点の値が実際に負担になる場合があります。ゼロに近い浮動小数点の方が正確です。固定距離がより望ましい距離になるのは、長距離のみです。答えは、単にコンテキストに依存するということです。

銀河のようなものでは、参照フレームを使用できます。太陽系に巨大なスケールを使用し、太陽の中心(または同様の点)をシステム内のあらゆるものの原点として使用します。このシステムを使用すると、いわばケーキを食べて食べることができ、想像するのは難しくありません。

IIRC、Infinityの開発者は、彼のインタビューの1つでスケールの問題を継続的に繰り返していると述べました。


どのゲームでも、浮動小数点の「ゼロに近い」精度が必要になることはほとんどありません。1メートル単位の場合、10ビットの精度でサブミリメートルの精度が得られますが、32ビット値で動けない場合でも各方向で4000kmを超えるモデルを作成できます。ミリメートルよりも高い精度が必要な場合は、確かに数ビットをシフトできます。宇宙ゲームで64ビット値に移行すると、ボリューム全体にわたって一定の精度を持つソーラーシステム(またはそれ以上?)が得られます。
ダッシュトムバン

確かに。そして、それがあなたが銀河サイズの世界で基準点として太陽系の太陽を使う理由です!重要なのは、精度を処理するために選択した方法は、いずれにしてもテーブルに何ももたらさないということです。それは議論の余地がないので、ライブラリ/ハードウェアが調整されているものを使用することもできます。
-Rushyo

ちなみに、私はゲームに取り組み、各方向で4000kmを超えるモデルを作成する必要がありました。他のプロジェクトのコードとの互換性のために、位置に32ビットを使用する必要がありました。コードの再利用と今日のゲーム世界の規模に課せられた商業的要求を考えると、それは理論的な問題ではありません。

1

まだ行っていない場合は、GameDev.netのPlanet Renderingチュートリアルを確認してください。空間分割に関しては、1つの解決策は2つの別々の位置変数を保持することです-1つはマクロスケール、もう1つはマイクロスケールです。これは非常にうまく機能します(テスト済み)。

正確な解決策は、エンジンの極端な距離をどのように処理するかによって異なります。ジャンプゲートを計画しますか、それとも時間圧縮を計画しますか。


1

理由の1つは、浮動小数点演算が「十分」である(または少なくともそれが十分である)ため、かなり正確な結果が迅速に生成されることです。

浮動小数点演算の制限を認識し、それに対処するためにアルゴリズムを変更する限り(Andrew Russellの答えを参照)、「機能する」コードを生成します。


-1

ゲームを書いています。私のゲーム/プログラムでは、かなり固定されたカメラを使用して原点に宇宙船を描き、別のカメラを使用して惑星を描きます。そして、これらの2つのことは私のために問題を処理しますが、私の惑星はまだあまり詳しくありません。アンドリューラッセルが世界を動かすことについて述べたソリューションについて(そして、カメラとその住民を原点に戻すと仮定しています)、ゲームをネットワークゲームにすることを計画しているなら、私は本当にそれを試みません。各クライアントの動きに基づいてサーバーアプリケーションで世界を移動した場合、世界はポジションを獲得するのに苦労することになります。そして、プレイしているすべての人から常にその位置を占めており、これは大きな不具合です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.