2

私は Ogre と NxOgre の両方を使用しています。どちらも、コンパイラ フラグに依存するか、依存するRealtypedef を持っています。これにより、コンパイラの警告のほとんどが次のようになりました。floatdouble

warning C4305: 'argument' : truncation from 'double' to 'Ogre::Real'

たとえば、変数を 0.1 で初期化する場合。通常は 0.1f を使用しますが、コンパイラ フラグを倍精度に変更すると、逆の警告が表示されます。どちらかを選んでそのままにしておくのがおそらく最善だと思いますが、可能であればどちらの構成でも機能するようにこれらを書きたいと思います。

修正の 1 つは、問題#pragma warning (disable : 4305)が発生したファイルで使用することです。この警告が表示されないことで隠れる可能性のある、より複雑な問題が他にあるかどうかはわかりません。コード全体に広がらないように、ヘッダー ファイルにもこれらをプッシュ アンド ポップすることを理解しています。

もう 1 つは、次のような精度コンパイラ フラグに基づいてマクロを作成することです。

#if OGRE_DOUBLE_PRECISION
    #define INIT_REAL(x) (x)
#else
    #define INIT_REAL(x) static_cast<float>( x )
#endif

これまでに行われたすべての変数の初期化を変更する必要がありますが、少なくとも将来の証拠になります。

好みや考えていないことはありますか?

4

4 に答える 4

3

簡単な解決策は、キャストを追加することです。

static_cast<Ogre::Real>(0.1);

または、変換を行う関数を作成することもできます (マクロに似ていますが、マクロがもたらす厄介な問題をすべて回避します:

template <typename T>
inline Ogre::Real real(T val) { return static_cast<Ogre::Real>(val); } 

real(0.1)次に、値を として呼び出して取得できますOgre::Real

于 2010-05-25T13:03:49.560 に答える
1

常に浮動小数点リテラルを使用して初期化します。すべての浮動小数点値には、まったく同じ10進数を表すdouble値があります(ただし、これは、floatが表すことを意図した10進数値の最良の倍精度近似ではない場合があります)。

Visual Studioは、デバッグビルドでも、コンパイル時に拡張を実行するようですが、結果は必ずしも刺激的ではありません。1.1fをダブルパス1.1000000238418579を取る関数に渡すが、1.1をパス1.1000000000000001に渡す。(両方の値はウォッチウィンドウに応じて異なります。)

(もちろん、正確な表現を持つ数値、たとえば1.25fではそのような問題はありません。)

これが大したことであるかどうかにかかわらず、私は言うことができませんでしたが、あなたのゲームがフロートで問題なく実行される場合、それはすでに同様のレベルの不正確さを許容しています。

于 2010-05-25T20:22:40.827 に答える
1

明らかに、使用する型がプラットフォーム固有のものである場合、リテラルもそうあるべきです。TCHAR、CString、LPCTSTR などを使用すると同じ問題が発生します。さらに悪いcharことに、wchar_t.

したがって、私の好みは間違いなく初期化マクロになります。警告を回避することは危険です。

マクロを指定して、「float」リテラル タグを追加することもできます。

//#define DOUBLEPREC

#ifndef DOUBLEPREC
typedef float REAL;
#define INIT_REAL(r) (r##f)
#else
typedef double REAL;
#define INIT_REAL(r) r
#endif

REAL r = INIT_REAL(.1);
double d = INIT_REAL(.1);
float f = INIT_REAL(.1);
于 2010-05-25T11:51:31.933 に答える
0

私としては、タイプの 1 つに固執し、この警告を忘れます。とにかく、倍精度/単精度の fps への影響は最小限です (私のプロジェクトでは 3% 未満でした)。

また、(私の知る限り) 言及すると、DirectX と OpenGL は単精度で動作します。

この警告を適切な方法で本当に取り除きたい場合は、そのような#ifものを使用できますが、そうではありません。より良いアプローチは、次のようなものを作ることです

#if OGRE_DOUBLE_PRECISION == 1
    // Note that 
    typedef double Real;
#else
    typedef float Real;
#endif

また、Ogre::Real を型として使用してコードを作成することもできます (または、使いやすいように型定義します)。

于 2010-05-25T11:57:39.573 に答える