53

2 つのテキスト ボックスがあり、ユーザーは 2 つの正の整数を入力できます (Objective-C を使用)。目標は、2 つの数値の間のランダムな値を返すことです。

「man arc4random」を使用しましたが、まだ頭を包み込むことができません。いくつかのコードを思いつきましたが、バグがあります。

float lowerBound = lowerBoundNumber.text.floatValue;
float upperBound = upperBoundNumber.text.floatValue;
float rndValue;
//if lower bound is lowerbound < higherbound else switch the two around before randomizing.
if(lowerBound < upperBound)
{
    rndValue = (((float)arc4random()/0x100000000)*((upperBound-lowerBound)+lowerBound));
}
else 
{
    rndValue = (((float)arc4random()/0x100000000)*((lowerBound-upperBound)+upperBound));
}

今、値 0 と 3 を入力すると、問題なく動作するようです。ただし、数値 10 と 15 を使用すると、「rndValue」で 1.0000000 または 2.000000 という低い値を取得できます。

アルゴリズムを詳しく説明する必要がありますか、それとも arc4random の使用方法を変更する必要がありますか?

4

6 に答える 6

126

次のように単純に整数値を使用できます。

int lowerBound = ...
int upperBound = ...
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);

それとも、lowerBound と upperBound の間に浮動小数点数を含めたいということですか? その場合は、この質問を参照してください: https://stackoverflow.com/a/4579457/1265516

于 2012-03-13T04:34:22.353 に答える
7
-(int) generateRandomNumberWithlowerBound:(int)lowerBound
                               upperBound:(int)upperBound
{
    int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
    return rndValue;
}
于 2014-10-16T12:00:18.637 に答える
2

可能であれば、mod (%) で値をクランプすることは避けてください。使用している疑似乱数ジェネレーター ( などarc4random) がその全範囲で均一に分散された数値を提供するのに優れている場合でも、範囲内で均一に分散された数値を提供しない可能性があるためです。制限されたモジュロ範囲。

0x100000000stdint.h で利用できる便利な定数があるため、リテラル like を使用する必要もありません。

(float)arc4random() / UINT32_MAX

これにより、間隔 [0,1] でランダムなフロートが得られます。arc4random区間 [0, 2**32 - 1] の整数を返すことに注意してください。

これを必要な間隔に移動するには、最小値を追加し、ランダムな浮動小数点数に範囲のサイズを掛けるだけです。

lowerBound + ((float)arc4random() / UINT32_MAX) * (upperBound - lowerBound);

投稿したコードでは、ランダムフロートに混乱全体 (lowerBound + (upperBound - lowerBound)) を掛けていますが、これは実際には upperBound と同じです。そのため、意図した下限よりも少ない結果が得られます。

于 2014-07-19T02:50:35.330 に答える