RAND_MAX的值总是(2 ^ n)-1?

时间:2011-02-09 13:48:06

标签: c++ random

我对C ++感兴趣,但我怀疑只是导入C标准定义。我相信标准所说的答案是肯定的,但我对实践中的答案最感兴趣。

如果RAND_MAX总是(2 ^ n)-1,那么这简化了处理最近将代码从MinGW GCC移动到Linux GCC的问题。 RAND_MAX似乎更大(我没有检查,但可能等于INT_MAX或符号是什么),所以一些旧的天真写的RAND_MAX - 不够大 - 所以 - 解决它的代码适得其反。现在我需要确定我需要这个库的一般性,考虑到编写正确处理溢出可能性的代码的繁琐,而不考虑例如int的宽度。

无论如何,有没有合理广泛使用的C ++编译器为RAND_MAX使用(2 ^ n)-1以外的东西?

另外,我是否正确((RAND_MAX |(RAND_MAX>>>>>&n;&n;&n;&n;&n;&n;&n; RAND_MAX)始终且仅当RAND_MAX等于((2 ^ n)-1)对于某些无符号整数n时才为真。我认为RAND_MAX在技术上是一个整数,但是有一个负值或小数值是没有意义的,所以我认为我可以安全地打折。比特摆弄通常不会打扰我,但我一直认为表情看起来不对,我无法弄清楚原因。

最后,虽然在我有自己的解决方案之前我不会感到高兴,应该我用于随机数而不是自己编写?我需要0 <= x <0的范围内的随机数。参数,我特别希望所有数字的概率相等。例如,取(rand()%upperbound)会偏向较小的值,特别是当上限很大时 - 我想避免这种情况。

是否存在Boost或C ++ 0x的事情?

修改

在页面侧面的“相关”位中显示的内容显示确实有一种方法可以获得具有给定下限和上限的随机数。

7 个答案:

答案 0 :(得分:5)

  • 我不知道任何RAND_MAX不低于2的幂的实现,但标准不强制要求;

  • ((RAND_MAX |(RAND_MAX&gt;&gt;&gt;&1;))== RAND_MAX)确实是一种测试RAND_MAX是否小于2的幂的方法。

  • 我正在使用

    int alea(int n){ 
      assert (0 < n && n <= RAND_MAX); 
      int partSize = 
        n == RAND_MAX ? 1 : 1 + (RAND_MAX-n)/(n+1); 
      int maxUsefull = partSize * n + (partSize-1); 
      int draw; 
      do { 
        draw = rand(); 
      } while (draw > maxUsefull); 
      return draw/partSize; 
    }
    

使rand()中的随机数尽可能均匀分布。

答案 1 :(得分:4)

对于使用(变体a)线性同余生成器(大多数)的rand的实现,则RAND_MAX将是素数,不一定是2 ^ n - 1的形式(“Mersenne”素“)。

此外,2 ^ 31-1是素数,但如果n不是素数,则2 ^ n - 1不是素数。

(的确,如果n = ab,那么2 ^ n - 1 =(2 ^ a - 1)(1 + 2 ^ b + 2 ^(2b)+ ...))

大约2 ^ 64,唯一的梅森素数是2 ^ 61 - 1。

如果对随机数生成有任何半严重要求,你应该真的避免使用线性同余生成器。实际上,我会说除了俄罗斯方块游戏之外,你应该避免使用rand()来自C库。

答案 2 :(得分:3)

我不知道RAND_MAX上的保证是什么,但是如果可能的话你最好避免它,因为它的实现数量很多,因为它在今天的应用程序中很快就开始循环。描述了统一分布here

我推荐Boost.RandomMersenne twister生成器代表了速度,内存使用和质量之间的良好折衷。

答案 3 :(得分:1)

在GCC(4.6)中RAND_MAX = 0x7FFFFFFF(31位) 在MS Visual Studio(2012)中,RAND_MAX = 0x7FFF(15位)

答案 4 :(得分:1)

在Embarcadero C ++ Builder中,stdlib.h中定义了两个变量:

/* Maximum value returned by "rand" function*/
#define RAND_MAX  0x7FFFU

/* Maximum value returned by "_lrand" function (also used by random() macro)*/
#define LRAND_MAX 0x7FFFFFFFU

答案 5 :(得分:1)

在标准GNU头文件stdlib.h中,有一个RAND_MAX的定义,它应该是系统中唯一的定义:

#define RAND_MAX    2147483647

值2147483647 = 0x7fffffff是最大的无符号32位整数。

stdlib.h中定义的rand函数在标准GNU环境中是可靠的,有一点需要注意:多线程(pthread)环境需要pthread代码进行同步才能保护rand(),srand()和rand_r()调用,因为它们不可重入。有关说明,请参阅man page for srand

不应在系统中的任何其他位置定义RAND_MAX。如果您看到RAND_MAX的值不同或者在stdlib.h之外的某处看到RAND_MAX的定义,那么这必须是非标准的非可移植环境。 Windows因使标准化和可移植性变得困难(例如套接字实现和API)而臭名昭着。

答案 6 :(得分:1)

根据ISO C(至少C99至C17)和POSIX(2016年第7版),RAND_MAX至少应为32767,即2 ^ 15−1,并且没有其他限制。

在GNU / Linux下,为保证与RAND_MAX函数有关的POSIX的一致性,在所有体系结构上,random()都必须正好是2147483647 = 2 ^ 31−1:POSIX指定返回值的范围是0到2 ^ 31-1,Linux random(3)手册页记录的范围是0到RAND_MAX