在范围内生成随机数

3

我正在为iOS和Android编写一个应用程序。在启动时,我试图获取1到6之间的随机数。

iOS(Objective-C):


```objc int random = arc4random_uniform(6) + 1; ```
int random = rand() % (6 - 1) + 1;

安卓(Java):

Random random = new Random();
int num = random.nextInt(6)+1;

无论哪种情况,它们每次都会返回3。
从我阅读的其他问题中可以看出,人们之所以遇到相同的问题,是因为他们在循环随机数并不断重新实例化Random对象。但我只想要一个随机数,所以我只实例化一次。
那么,如何使这些代码片段获得1-6的数字,而不仅仅是3呢?

随机数 random = new Random(long seed); 这个有帮助吗?http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html - kosa
1
@Nambari 在理论上,无参数构造函数应该使用“某些相对独特的东西”初始化生成器。 - Michał Kosmulski
@MichałKosmulski:同意,但是当 OP 想要每个操作系统的不同内容时,需要使用种子生成器而不是默认值。就像 David 的回答一样。 - kosa
谢谢大家的想法,Martijn清晰地回答了两个问题。 - Ryan
对于Java,真的要考虑使用SecureRandom类。对于Objective-C,请考虑使用arc4random和arc4random_uniform。它们具有加密质量且易于使用。 - zaph
5个回答

4

关于Objective-C部分,我可以告诉你需要种下随机数,像这样:

srand(time(0)); // seed it using the current time

对于Java部分,new Random()构造函数会自动在默认的JVM中为桌面应用程序设置种子,但在Android上不会。在Android上,它使用默认的种子值。
Random rand = new Random(System.nanoTime());

谢谢你回答我的问题,我在Android上尝试使用System.currentTimeMillis作为种子。它似乎不太随机,但我相信它是随机的,只是我太匆忙没有彻底测试它。再次感谢。 - Ryan
srand()是一个非常糟糕的选择,请考虑使用arc4random() - zaph
@Zaph:谢谢你提供的信息。我之前不知道这个函数。但是就目前我的项目而言,我还是会使用rand(),因为我想要能够定义种子。 - Martijn Courteaux
如果你因为某种原因需要可重复性,比如测试,那么srand()是一个不错的选择。否则,arc4random()及其类似函数是更好的选择,它们接近真正的随机数。使用时间作为种子是一个不安全的选择,适用于安全用途。 - zaph

3

如果可能的话,最好的解决方案是使用arc4random_uniform,它在iOS 4.3及以上版本中可用。它消除了通常由模运算引入的偏差。

+ (u_int32_t)randomInRangeLo:(u_int32_t)loBound toHi:(u_int32_t)hiBound {
    int32_t   range = hiBound - loBound + 1;
    return loBound + arc4random_uniform(range);
}

请注意,不需要进行播种,并且它可以生成密码学安全的随机数。

太棒了,感谢提供这些信息。对于我正在做的事情来说,安全性和完全随机性并不是主要问题,但了解这些信息很有帮助。 - Ryan

3
在Objective-C中,你可以使用推荐的arc4random()函数,它不需要种子。你可以这样使用它:
int random = (arc4random() % 5) + 1;

这个函数与 rand() 相比的一个巨大优势是它有两倍于 rand() 的范围,从而允许生成“更随机”的数字。

2

关于Android上的随机数生成,我不确定,但在其他情况下,你可能希望使用一些相对唯一的种子来初始化Random实例,比如系统时间。

Random r = new Random(System.currentTimeMillis());


很酷,我实际上尝试过了,但是忘记在我的帖子中提到了。它似乎几乎每次都按顺序1、2、3、4、5、6进行,所以我认为它没有起作用,但我会再次检查。 - Ryan

0

我尝试了Java部分,对我来说运行得很好,但你可以尝试使用时间作为种子来实例化Random:

    java.util.Date d = new java.util.Date();
    Random random = new Random(d.getTime());
    int num = random.nextInt(6)+1;
    System.out.println(num);

这可能与我尝试的类似,使用System.currentTimeMillis。感谢您的答案。 - Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接