Andrew Koenig撰写的 Accelerated C ++ 问题7-9问道:
7-9。 (困难)§7.4.4/ 135中nrand的实现不会 适用于大于RAND_MAX的参数。通常,这种限制是 没问题,因为RAND_MAX通常是最大可能的整数 无论如何。然而,有些实现RAND_MAX 远小于最大可能的整数。例如,它是 RAND_MAX是32767(2 ^ 15 -1)并且最大的并不罕见 可能的整数为2147483647(2 ^ 31 -1)。重新实现这一点 它适用于所有n值。
如果n > RAN_MAX
我的想法是
double temp = n/RAN_MAX + .5;
int mult = temp;
int randomNum = 0;
for (int i = 0; i != mult; mult++)
randomNum += rand();
然后测试以查看randomNum< ñ。这会产生随机数> RAND_MAX
吗?我不知道如何使用比我的计算机可以处理的更大的整数,所以我认为没有任何真正的方法可以告诉。
答案 0 :(得分:2)
如果你真的乱用整数大于计算机可以处理的整数,那就太复杂了。
但对于大于int
的整数,你有几个选项,其中包括:unsigned int
,long
,unsigned long
,long long
,{{1}在增加大的顺序。根据您的架构,数字变得多大。
例如,在我的机器上,我有以下内容:
unsigned long long
因此,正如您所看到的,您可以使数字远大于Data Type: Bytes Minimum Maximum
Short SInt: 2 -32768 32767
Short UInt: 2 0 65535
UInt: 4 0 4294967295
SInt: 4 -2147483648 2147483647
ULong: 8 0 18446744073709551615
SLong: 8 -9223372036854775808 9223372036854775807
ULong Long: 8 0 18446744073709551615
SLong Long: 8 -9223372036854775808 9223372036854775807
和32767。
执行此操作的一种方法如下:
int
但是,由于浮点数的离散性,这可能意味着某些值将永远不会出现在输出流中。
C ++ 11有一个库,可以解决这个问题和你提到的问题。其用法的一个例子是:
double a=rand()/(double)RAND_MAX;
unsigned long long random_n=(unsigned long long)(BIG_MAXIMUM_NUMBER*a);
只需更改数据类型即可满足您的大量需求。
另一种看待这种情况的方法是我们可以将const int min = 100000;
const int max = 1000000;
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(min,max);
int random_int = distribution(generator);
解释为返回一个位字段,因为它是一个统一的PRNG,所有位字段都是同样可能的。然后,我们可以对rand()
进行多次调用,以获得多个同样可能的位字段,并将这些字段合并为大数字。以下是我们如何通过两个8位随机数生成一个16位随机数:
rand()
uint16 a=(uint16)(rand()&255);
uint16 b=(uint16)(rand()&255);
uint16 random_int=b<<8 | a;
仅保留任何数字rand()&255
返回的8个最低有效位;也就是说,它只保留rand()
的最后一个字节。
rand()
将此字节转换为无符号的16位数字。
(uint16)
将a<<8
8位的位向左移,这样可以安全地添加a
。
但是如果b
返回一个有符号值,那么最重要的位总是0或1呢?然后我们可以执行以下操作:
rand()
我们左移uint16 a=(uint16)(rand()&255);
uint16 b=(uint16)(rand()&255);
uint16 c=(uint16)(rand()&1);
uint16 random_int=c<<14 | b<<7 | a;
只有7位,因此第8个最低有效位是随机的。这意味着第14和第15个最低有效位将是非随机的。由于我们想要模仿b
的行为,我们将第15个最低有效位保持为非随机,并抓住一个随机位左移到第14个LSB的位置。