web-dev-qa-db-ja.com

Objective-Cで2つの数値間の乱数を生成する

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の使用方法を変更する必要がありますか?

49
Demasterpl

次のような整数値を使用できます。

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

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

122
eveningsun

次のコードには、ランダムな出力番号として最小AND MAXIMUM値が含まれています。

_- (NSInteger)randomNumberBetween:(NSInteger)min maxNumber:(NSInteger)max
{
    return min + arc4random_uniform((uint32_t)(max - min + 1));
}
_

更新:
@ rmaddyが示唆したように、arc4random() % upper_boundarc4random_uniform(upper_bound)に置き換えることで回答を編集しました。
そして、詳細は arc4random_uniform を参照してください。

Update2:
@ bicycleが示すように、arc4random_uniform()のuint32_tにキャストを挿入することで、回答を更新しました。

65
inexcii
-(int) generateRandomNumberWithlowerBound:(int)lowerBound
                               upperBound:(int)upperBound
{
    int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
    return rndValue;
}
7
Abo3atef

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

また、stdint.hには便利な定数があるため、0x100000000のようなリテラルを使用する必要はありません。

(float)arc4random() / UINT32_MAX

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

これを希望する間隔に移動するには、最小値を追加し、ランダムフロートに範囲のサイズを掛けます。

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

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

2
Aaron Golden

Objective-C関数

-(int)getRandomNumberBetween:(int)from to:(int)to
{
    return (int)from + arc4random() % (to-from+1);
}

スイフト:

func getRandomNumberBetween(_ from: Int, to: Int) -> Int 
{
    return Int(from) + arc4random() % (to - from + 1)
}

どこでも呼び出す

int OTP = [self getRandomNumberBetween:10 to:99];
NSLog(@"OTP IS %ld",(long)OTP);
NSLog(@"OTP IS %@",[NSString stringWithFormat @"%ld",(long)OTP]);

Swiftの場合:

var OTP: Int = getRandomNumberBetween(10, to: 99)
0
Raj Aryan

In Swift:

let otp = Int(arc4random_uniform(6))

これを試して。

0
user9260747