【问题标题】:Why I keep getting the same random values? [duplicate]为什么我不断得到相同的随机值? [复制]
【发布时间】:2012-04-25 08:53:28
【问题描述】:

可能重复:
why do i always get the same sequence of random numbers with rand()?

我感到困惑的是,即使使用不同的程序(在同一台机器上)来运行/编译,并且在取消函数(之前和之后)的值之后.. 没关系.. 每次我运行它时,我都会得到相同的“随机”数字。我发誓这不是它应该如何工作的......我将尽可能简单地说明......

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {

    int rPrimitive = 0;  rPrimitive = 1 + rand() % 50;
    NSNumber *rObject = nil; rObject = [NSNumber numberWithInt:rand() % 10];
    NSLog(@"%i  %@", rPrimitive, rObject);

    rPrimitive = 0;   rObject = nil;
    NSLog(@"%i  %@", rPrimitive, rObject);
    return 0;           
}

在 TextMate 中运行:

i686-apple-darwin11-llvm-gcc-4.2
8  9
0  (null)

在 CodeRunner 中运行它:

i686-apple-darwin11-llvm-gcc-4.2
8  9
0  (null)

如果您愿意,可以运行一百万次。你可以猜到它永远是什么。为什么会这样?为什么哦为什么这是“它是这样的”?

【问题讨论】:

  • 我的问题确实与以下事实有关,即这些结果跨越操作系统/内存的逻辑划分,并且尽管将 null 分配给值,但它们仍然发生,而不是 rand 本身。
  • @alexgray 这只是意味着不同的操作系统使用相同的 PRNG,这并不意外。设置 null 不会改变任何东西,因为这是 rand 的预期行为,而不是内存错误。
  • 请不要删除自动生成的重复链接。您可以标记此问题以引起版主注意,或在 Meta Stack Exchange 上提出问题,如果您认为应该重新打开它。

标签: objective-c c random


【解决方案1】:

之所以这样是因为rand 是一个伪随机数生成器,这意味着它不会生成真正的随机数(这实际上是一件非常困难的事情)。它使用“种子”生成序列中的下一个数字,并且在执行开始时,种子总是设置为相同的值(1 左右),所以如果你不改变种子,你总是会得到相同的随机数序列。您可以使用 srand(time(NULL)); 之类的东西来根据时间播种随机数生成器,或者您可以使用被认为足够强大以用于加密目的的随机数生成器 arc4random

您可能会想“为什么会这样?”,但在某些情况下,您希望多次生成同一系列“随机数”。

【讨论】:

  • 啊,是的,我以前使用过 arc4random,这就是为什么这看起来很奇怪。确实将 #define rand() (arc4random() % ((unsigned)RAND_MAX + 1)) 放在 main 之前再次给宇宙带来了意义。谢谢。
  • 在确定性机器(又称计算机)中,“生成”真正的随机数是不可能的,并不困难。你需要一个外部随机源。
  • @alexgray 即使这样做,您仍然在使用伪随机数,只是碰巧 arc4random 用比常数值1 更独特的东西为自己播种
  • @AaronDufour:OpenBSD 的“外部来源”包括鼠标移动、网络活动等。当然,它仍然不是真正的随机,但对于几乎所有实际用途而言,它是足够随机的。而且,这不是不可能的,这很困难。见here
  • @dreamlax 这些都不涉及“产生”随机性。他们使用外部资源,我指出这是获得真正随机数的唯一方法。
【解决方案2】:

因为数字不是随机的,所以它们是pseudorandom。它们是根据一种算法生成的,在给定相同的初始种子的情况下,该算法将始终产生相同的输出。您没有播种 PRNG,因此它使用默认的常量种子。

如果您使用不太可预测的内容(例如当前时间和/或 PID)为 PRNG 播种,则每次都会得到不同的结果。对于rand(3),您需要使用srand(3) 为其播种。

【讨论】:

    【解决方案3】:

    这就是为什么(来自rand 手册页):

       If no seed value is provided,  the  rand()  function  is  automatically
       seeded with a value of 1.
    

    因为它总是以相同的数字作为种子,所以它总是会产生相同的数字序列。要让它在每次运行时产生不同的序列,您需要在每次运行时使用不同的种子。您可以使用srand() 设置种子。

    【讨论】:

    • 请注意,常见的模式是srand(time(NULL)),这样程序的连续运行就会得到不同的种子。
    猜你喜欢
    • 2011-11-29
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 2014-05-18
    相关资源
    最近更新 更多