2012-03-13 19 views
44

İki metin kutusu kullanıyorum ve kullanıcı 2 pozitif tamsayı girebilir (Objective-C kullanarak). Amaç, iki sayı arasında rastgele bir değer döndürmektir.Objective-C'de İki Sayı Arasında Rastgele Sayılar Oluşturun

"Man arc4random" 'u kullandım ve hala kafamın etrafına dolamıyorum. Bazı kodlarla geldim ama bu adam.

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)); 
} 

Şu anda 0 ve 3 değerlerini kullanırsam, gayet iyi görünüyor. Ancak 10 ve 15 numaralarını kullanırsam hala "rndValue" için 1.0000000 veya 2.000000 gibi düşük değerler alabilirim.

Algoritmamı detaylandırmalı mıyım yoksa arc4random kullanma şeklini değiştirmem gerekiyor mu?

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

Yoksa demek eğer LOWERBOUND UPPERBOUND arasındaki şamandıra numarasını kullanabilirsiniz:

+0

http://iphonedevelopment.blogspot.com/2008/10/random-thoughts-rand-vs-arc4random.html – Andrew

+1

Parantezleriniz yanlış. Açık parantezi '' 've ardından parantezin ardından kapatın; Yine de hala yuvarlama sorunlarınız var. –

+2

Genel formül 'minDeğer + ((maksDeğer - minDeğer) * rnd())' Burada 'rnd()', 0,0 ve 1,0 arasında bir rasgele kayan nokta değeri döndürür, aradığınız değeri döndürür. Bunu Obj-C'ye dönüştürmek ve ihtiyaçlarınıza göre optimize etmek için size bırakıyorum. –

cevap

57

şu kod rasgele çıkış numarası olarak asgari VE MAKSİMUM değerini içerir:
Ben arc4random_uniform(upper_bound) ile arc4random() % upper_bound değiştirerek cevap düzenlendi: Güncelleme

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

@admaddy önerdi.
Ve detaylar için arc4random_uniform referansı.

Update2:
Bicycle belirttiği gibi arc4random_uniform() numaralı telefona uint32_t dosyasına bir döküm ekleyerek yanıtı güncelleştirdim.

+6

Dönüş arc4random_uniform (maks - min + 1) + min; 'işlevini kullanmak daha da iyidir. – rmaddy

+0

@rmaddy Haklısınız! Cevabımı güncelledim ve öneri için çok teşekkür ederim. – inexcii

+0

@Demasterpl bir kayan nokta sonucu istemiyor mu? –

2

Mümkünse mod (%) ile kenetleme değerlerinden kaçınmalısınız, çünkü kullandığınız sözde rasgele sayı üreteci (arc4random gibi) bile tam aralıkta eşit dağıtılmış sayılar sunmakta iyi olsa da kısıtlı modulo aralığında düzgün şekilde dağıtılmış sayılar sağlar.

stdint.h mevcut elverişli bir sabit olduğundan Ayrıca 0x100000000 gibi bir hazır kullanmak gerekmez: aralığında size rastgele bir şamandıra verecektir

(float)arc4random()/UINT32_MAX 

[0,1] . arc4random'un [0, 2 ** 32 - 1] aralığında bir tam sayı döndürdüğünü unutmayın.

, istediğiniz aralık içine bu taşımak için sadece minimum değer katmak ve aralığın boyutuna göre rastgele şamandıra çarpın:

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

Eğer rastgele şamandıra çarparak ediyoruz yayınlanmıştır kodunda tüm karmaşa ile (lowerBound + (upperBound - lowerBound)), bu sadece upperBound'a eşittir. İşte bu yüzden hedeflediğiniz alt sınırdan daha az sonuç alıyorsunuz.

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

Objective-C Fonksiyonu:

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

Swift:

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

tarafından yerde arayın:

Swift için

:

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

Swift in:

let otp = Int(arc4random_uniform(6)) 

bu deneyin.