1

メルセンヌツイスター乱数ジェネレーターの単純なラッパーがあります。目的は、ジェネレーターによって返される数(0から1の間)を引数で定義された制限(開始と終了)の間でスケーリングすることです。

だから私の機能は

inline float xlRandomFloat(float begin, float end) {return (begin+((end-begin)*genrand_real2()));}

genrand_real2()関数の実装は重要ではないと思いますが、間違っている場合はここで見つけることができます

問題は、関数が翻訳された結果を返さないことです。スケーリング((begin-end)を掛ける)は正しく機能しているようですが、beginの加算は返されないようです。

したがって、xlRandomFloat(5,10)を呼び出すと、0から5までの値が得られます。

GDBでデバッグし、print関数を使用すると、正しい結果が表示されます。それで私は物事を線に分けて何が起こるか見てみました

inline float xlRandomFloat(float begin, float end) {
    float ret;
    ret=(((end-begin)*genrand_real2()));
    ret+=begin;
    return ret;};

デバッグ時には、最初の行からgenrand_real2()関数に直接ジャンプし、他のすべてを完全にスキップしました。それは本当に混乱していたので、インライン化と関係があるのではないかと思いました。この.hppファイルから.cppにファイルを移動し、inlineキーワードを削除すると、すべてが正しく機能します。

しかし、なぜこの動作が発生するのでしょうか。また、この関数をどのようにインライン化できますか?また、これが適切かどうかはわかりませんが、ソースに変更を加えたときに、Makeのコンパイルで何もする必要がないと表示されることがよくあります。通常、ソースの変更を取得してそれに応じて再構築することを期待しているため、これは珍しいことです。

何か案は。

ありがとう

ゼナ

4

2 に答える 2

1

あなたのコードは完全に素晴らしいです、あなたがコンパイルしている方法に何か問題があるに違いありません。Makefileに適切な依存関係があることを確認してください。ソースファイルは、それらに含まれるヘッダーファイルに依存する必要があります。これらの依存関係の追跡が手動で行われることはめったになく、通常は非常に小さなプロジェクトの場合のみです。通常、これらはなどのツールによって生成されmakedependます。

インライン化が問題の原因であるかどうかを確認するには、-O0GCCで(dash Capital-oh zero)オプションを使用して、すべての最適化を無効にします。また、。を使用してデバッグシンボルを有効にして-gください。

于 2009-04-21T04:21:19.207 に答える
1

さて、ここでいくつかのことが働いています。

最初に、デバッグで、多かれ少なかれ予想される動作として私が考えるものを説明します。これは、関数をインライン化するときに、関数の元の問題に対応するコードが生成されないためです。だから、そこにある最初のステートメントは

ret=(((end-begin)*genrand_real2()));

その最初のステップは、を呼び出すことgenrand_real2()です。genrand_real2(インラインの場合、息を呑むような一時停止なしで、その最初のステートメントになります。

次に、自分が思っているコードを実際に実行していることを確認します。クリーンなディレクトリから作成してみてください。一部のC++コンパイラは、コンパイルを高速化するために保存するプリコンパイル済みの部分を作成します。インライン定義がヘッダーファイルから完全に削除またはコメントアウトされていることを確認してください。m

第3に、インラインを使用して非常に単純なプログラムを作成し、期待どおりに動作することを確認します。

于 2009-04-21T04:41:10.970 に答える