2012-03-13 75 views
44

我有两个文本框,用户可以输入2个正整数(使用Objective-C)。目标是在这两个数字之间返回一个随机值。在Objective-C中的两个数字之间生成随机数字

我已经使用过“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的方式?

+0

http://iphonedevelopment.blogspot.com/2008/10/random-thoughts-rand-vs-arc4random.html – Andrew 2012-03-13 04:32:35

+1

你的括号是错误的。删除'*'后面的左括号和';'前面的右括号。尽管你仍然有四舍五入的问题。 – 2012-03-13 04:34:53

+2

通用公式'minValue +((maxValue - minValue)* rnd())'其中'rnd()'返回0.0到1.0之间的随机浮点值将返回您正在查找的值。我把它留给你转换成Obj-C并优化它以适应你的需求。 – 2012-03-13 04:34:58

回答

116

你可以简单地用整数值是这样的:

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

或者,如果你的意思是你想包括下界和上界之间的浮点数?如果是的话,请参考这个问题:https://stackoverflow.com/a/4579457/1265516

+1

int不是浮动 – Andrew 2012-03-13 04:37:24

+0

对不起,我误解了你的问题,请参阅最新的答案。 – eveningsun 2012-03-13 04:40:09

+2

该代码不包含upperBound作为随机输出,请参阅下面的答案作为修复。 – inexcii 2013-12-11 07:38:04

57

下面的代码包括最小和最大值作为随机输出数:

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

更新:
我用arc4random_uniform(upper_bound)更换arc4random() % upper_bound编辑答案正如@rmaddy所建议的那样。
有关详细信息,请参阅arc4random_uniform

更新2:
我更新了答案,通过在@bicycle指示的位置插入一个投影到uint32_t arc4random_uniform()

+6

使用'return arc4random_uniform(max - min + 1)+ min;'更好。 – rmaddy 2014-07-17 18:11:51

+0

@rmaddy你是对的!我已经更新了我的答案,并非常感谢您的建议。 – inexcii 2014-07-19 02:23:29

+0

@Demasterpl不需要浮点结果吗? – 2014-07-19 02:53:03

2

如果可以的话,您应该避免使用mod(%)来限制值,因为即使您使用的伪随机数生成器(如arc4random)擅长于提供全范围的均匀分布的数字,在限制模数范围内提供均匀分布的数字。

你也不需要使用一个文字像0x100000000因为在stdint.h提供一个方便的常数:

(float)arc4random()/UINT32_MAX 

这将使你在区间随机浮动[0,1] 。请注意,arc4random在区间[0,2 ** 32 - 1]中返回一个整数。

要移动到这个你想要的时间间隔,你只需要添加您的最小值和你的范围的大小乘以随机浮动:

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

在你发布你乘以随机浮点代码由整个混乱(lowerBound +(upperBound - lowerBound)),这实际上就等于upperBound。这就是为什么你仍然得到的结果低于你想要的下限。

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

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

对于斯威夫特:

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

在斯威夫特:

let otp = Int(arc4random_uniform(6)) 

试试这个。