2011-07-27 24 views
0

符号付きintをgsl_rng_uniform_int (const gsl_rng * r, unsigned long int n)に渡したいとします。私が渡している符号付きintはゼロ以上です。この関数は0nの間の数値を返します。正の符号付き整数を渡すと、符号付き整数の範囲内の値が返されます。私はその後、返された値を署名付きintに格納します。明白な期待された動作でこれを行う最もクリーンな方法は何ですか?私は64ビットLinuxマシン上の64ビットコンパイラを使用しています。符号なし整数から符号付き整数への変換または逆の変換

更新 申し訳ございません。無視してください。私のコードの問題は実際には他の場所にありました。私はgdbの出力を誤解しました。

答えて

2

スタート

if (input <= 0) { panic(); } 
unsigned long rawresult = gsl_rng_uniform_int(r, input); 
if (rawresult > INT_MAX) { panic(); } 
int result = (int) rawresult; 

これらの行ができヘルパー関数でラップする:

int gsl_rng_uniform_signed(const gsl_rng *r, int input) { 
    if (input <= 0) { panic(); } 
    unsigned long rawresult = gsl_rng_uniform_int(r, input); 
    if (rawresult > INT_MAX) { panic(); } 
    return (int) rawresult; 
} 

いずれの場合でも、入力のテストは、依存する関数の出力をテストするより便利です。gsl_rng_uniform_intを信頼すれば、入力をテストすれば十分です。

[編集:うわー、Googleは本当に積極的にインデックスを作成します。 gsl_rng_uniform_signedがまだ機能していないことを確認して見つけました。]

1

機能を使用すると、問題はないunsigned longunsigned intunsigned shortunsigned charに渡すことができunsigned longを想定している場合、標準はそれを保証します。

signedではなく、intを渡すと、関数によって非常に大きなintが評価されるため、正しい結果が得られません。

署名されたintが>= 0であるかどうかを確認するのが最善の方法です。

私はあなたの質問を正しく理解したと思います。

int input = something; 
int result = gsl_rng_uniform_int(r, input); 

そうコンパイラは危険な縮小変換について警告、そうに変更されます:

// 0 <= return value < input, so conversion is safe 
int result = (int) gsl_rng_uniform_int(r, input); 

または安全のために:と

関連する問題