如何在C中从整数的整个范围生成一个随机数?

如何在C中从整数的整个范围生成一个随机数?,c,random,C,Random,我知道如何(轻松地)生成0到100范围内的随机数。但是从int(假设sizeof(int)=4)的全范围(即从int\u MIN到int\u MAX)的随机数又如何呢 我不需要这个密码或类似的,但一个近似均匀的分布会很好,我需要很多这样的数字 我目前使用的方法是生成4个介于0到255(包括0到255)之间的随机数,并进行一些混乱的转换和位操作。我想知道是否有更好的方法。在我的系统上RAND_MAX是32767,是15位。因此,对于一个32位的无符号的只需调用三次,然后进行移位,或掩码等 unsi

我知道如何(轻松地)生成0到100范围内的随机数。但是从
int
(假设
sizeof(int)=4
)的全范围(即从
int\u MIN
int\u MAX
)的随机数又如何呢

我不需要这个密码或类似的,但一个近似均匀的分布会很好,我需要很多这样的数字


我目前使用的方法是生成4个介于0到255(包括0到255)之间的随机数,并进行一些混乱的转换和位操作。我想知道是否有更好的方法。

在我的系统上
RAND_MAX
是32767,是15位。因此,对于一个32位的
无符号的
只需调用三次,然后进行移位,或掩码等

unsigned const number = minimum + (rand() % (maximum - minimum + 1))

在我的系统上,
RAND_MAX
是32767,是15位。因此,对于一个32位的
无符号的
只需调用三次,然后进行移位,或掩码等

unsigned const number = minimum + (rand() % (maximum - minimum + 1))

作为参考,我添加了我一直在使用的内容:

3294784390
3748022412
4088204778
int随机_int(无效){
断言(sizeof(unsigned int)=sizeof(int));
无符号整数累加=0;
尺寸i=0;
对于(;i作为参考,我添加了我一直在使用的内容:

3294784390
3748022412
4088204778
int随机_int(无效){
断言(sizeof(unsigned int)=sizeof(int));
无符号整数累加=0;
尺寸i=0;
对于(;ii通过积累足够的位来填充给定的类型,我们应该能够做一些工作,无论
rand()
的范围有多大,或者我们想要的结果有多大:

//可以是任何无符号类型。
类型def uint32\u t uint\u类型;
#定义RAND\u UINT\u MAX((UINT\u类型)-1)
单元类型和单元(无效)
{
//这些都是常数,系数可能是二的幂。
//因此,编译器有足够的信息展开
//循环,可以使用直接形式shl代替mul。
uint_类型系数=(uint_类型)RAND_MAX+1;
uint_类型系数_至_k=1;
uint_类型截止=系数?RAND_uint_最大值/系数:0;
uint_类型结果=0;
而(1){
结果+=rand()*系数从0到k;

如果(factor_to_k我们应该能够做一些有效的事情,不管
rand()
的范围是什么,或者我们仅仅通过积累足够的位来填充给定类型的结果是什么:

//可以是任何无符号类型。
类型def uint32\u t uint\u类型;
#定义RAND\u UINT\u MAX((UINT\u类型)-1)
单元类型和单元(无效)
{
//这些都是常数,系数可能是二的幂。
//因此,编译器有足够的信息展开
//循环,可以使用直接形式shl代替mul。
uint_类型系数=(uint_类型)RAND_MAX+1;
uint_类型系数_至_k=1;
uint_类型截止=系数?RAND_uint_最大值/系数:0;
uint_类型结果=0;
而(1){
结果+=rand()*系数从0到k;


如果(factor_to_k)没有,但显然我的google foo是缺少的?如果这很简单,那么请回答。@DanielJour他一整天都是这样。你做得很好:注意负数。你不想做二进制运算(或、xor和)带负数。@Olaf Pseudo random对我来说没问题。亲爱的投票人:请解释为什么投票给我。如果已经有类似的问题,请链接到它。(我搜索了很多)不,但显然我的google foo缺少?如果这是直截了当的,那么请回答。@DanielJour他一整天都是这样。你做得很好:只注意负数。你不想做二进制运算(或,xor,and)带负数。@Olaf伪随机对我来说没问题。亲爱的投票人:请解释你为什么投票给我。如果已经有类似的问题,请链接到它。(我搜索了很多)好的,我正在做类似的atm,但这更好,因为IIRC
RAND_MAX
保证至少有15位。(我只使用了其中的8个)这是不可移植的。当
RAND_MAX
不是32767时,
((unsigned)RAND()@chux使用
^
好,我正在做类似的atm,但这更好,因为IIRC
RAND_MAX
保证至少有15位。(我只使用了其中的8位)这是不可移植的。当
RAND_MAX
不是32767时,
((无符号)RAND()@chux最好使用
^
而不是
使用
UINT_MAX,INT_MAX,INT_MIN
assert(sizeof)(无符号INT)更强的鉴定测试…
。它也可以用于宏预处理,以便在运行时不编译而不失败。这仍然是一种很好的基本方法。(应该有此代码)。一个更强大的鉴定测试使用
UINT\u MAX、INT\u MAX、INT\u MIN
而不是
断言(sizeof(unsigned INT))…
。它也可以用于宏预处理,以便在运行时不编译而不是失败。这仍然是一种很好的基本方法。(应该有这段代码。)
int uniform_int_distribution(int min, int max)
{
    // [0,1) -> [min,max]
    double canonical = rand_uint() / (RAND_UINT_MAX + 1.0);
    return floor(canonical * (1.0 + max - min) + min);
}