私のケースはゲームプロジェクトに関連しているので、この質問をGameDevに投稿することを検討しましたが、これはより広範なプログラミングSEに適していると思いました。結局、この質問をそこに投稿したほうがいいかどうか教えてください。
私の理解から-そして私が間違っている場合は訂正してください-モバイル向けのゲーム開発(私の場合)は、固定小数点計算を採用することでかなりの利益を得ることができます。デバイスが浮動小数点を適切に処理するための設備が整っていない場合。
ただし、固定小数点には制限があり、特にオーバーフローがあります。したがって、私の質問は、ターゲットプラットフォームを考慮して固定小数点が最良の代替手段であると判断した場合、特定のプロジェクトの要件がそれらの使用を許可するかどうかを判断する方法です。
わかりやすくするために、問題が発生しているコードを少し共有したいと思います。
CIwVec2 calculateBezier(float t, CIwVec2 p0, CIwVec2 p1, CIwVec2 p2) {
float u = 1 - t;
CIwVec2 p = IW_FIXED(u * u) * p0; // (1 - t)²P0
p += IW_FIXED(2 * u * t) * p1; // 2(1 - t)tP1
p += IW_FIXED(t * t) * p2; // t²P2
return p;
}
このプロジェクトでは、C ++を使用し、固定小数点数の独自の実装(16ビットと32ビットの両方があり、現在は32ビットを使用しています)とVectorクラスが付属するMarmaladeSDKを使用しています。 (CIwVec2)は、位置と計算にその実装を使用します(上記のコードに示されているスカラー乗法を含む)。ああ、IW_FIXEDは、浮動小数点数を固定小数点に変換するための単なるマクロです。
上記のコードを実行しようとすると、乗算オーバーフローエラーが発生します。次のように値をデバッグします。
t = 0
u = 1 (which converts to 4096 in int32 fixed-point with IW_FIXED)
p0.x = 1638400 (400.0f with IW_FIXED_TO_FLOAT)
p0.y = 409600 (100.0f with IW_FIXED_TO_FLOAT)
正直なところ、固定小数点数については完全には理解していません。私はその考えを理解していますが、固定小数点演算は私には完全には明確ではありません(基数2に関連するほとんどの数学のクラスを捨てたに違いありません)。しかし、1.0f * 400.0fのような単純なものが固定小数点のオーバーフローを引き起こすという事実に、私は完全に困惑しています。
したがって、プロジェクトで固定小数点をサポートすることに問題はないと思いましたが、そうではないようです。このゲームはトップダウンの自動車ゲームであり、巨大なトラックなどはありませんが、少なくともデバイスの画面と同じ大きさ(またはさらに良いのはその解像度)である必要があります。タブレットの場合も、1.0f * 400.0fのような問題があるということは、固定小数点が問題外であることを意味します。
私はこの仮定で正しいですか?そして、将来のプロジェクトや同様の問題を抱えている他の人々のために、プロジェクト内の固定小数点数の実行可能性をどのように評価できますか?また、16ビットと32ビットのどちらを選択するかは大きなボーナスになります:)
(長い投稿をお詫び申し上げます。お時間をいただきありがとうございます!)
アップデート:
したがって、これまでの回答を少しまとめてください。理想的なシナリオは、ニーズに必要な範囲を持つように固定小数点数を実装することです(Mooing Duckの回答)。また、32ビットの数値を使用する操作の場合、最も安全な方法は、64ビットを使用して計算することです(timdayの回答とMaxのコメント)。ちなみに、マーマレードにはいくつかの「安全な固定乗算」関数がありますが、CIwVec2のスカラー乗算演算子のオーバーロード(IW_FIXED_MUL
下を使用し、安全に乗算されない)には当てはまりません。
そして最後に、私の特定のシナリオに関しては、マーマレード6.1の時点で、フロートを使用するだけがおそらく最良の解決策であるように思われます。
編集: マックスの答えは私の問題を本当に解決しましたが、それは主にマーマレードに固有のものだったためです。そのため、一般的に多くの人に役立つと思うので、MooingDuckの回答を選択しました。