我想在每次执行时得到0到10之间的随机浮点值,如果我不使用**srand(time(0))
,**我的随机值在每次执行时总是相同的。然而,如果我使用这个,我得到不同的值,但它在两次连续执行之间的变化是0.01。
所以我的问题是:
如果我使用srand(time(0) * 1000)
,我每次执行都会得到不同的随机数。这是一种正确的使用方式吗?或者会因为种子限制或特定时间的类似情况而溢出?
这里有一个简单的函数来获取0到10之间的不同浮点值
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(0) * 1000);
int i;
for (i = 0; i < 10; i++) {
float randomValue = ((float)rand() / RAND_MAX) * 10;
printf("Random float value %d: %.2f\n", i + 1, randomValue);
}
return 0;
}
字符串
5条答案
按热度按时间um6iljoc1#
如果我使用srand(time(0)* 1000),我每次执行都会得到不同的随机数。这样使用是正确的吗?或者会因为种子限制或特定时间的类似原因而溢出?
srand(time(0) * 1000)
比srand(time(0))
弱,原因如下。time()
typical返回一个整数。按1000缩放(与53 * 23相同)的结果是3个最低有效位为0的乘积。将该乘积转换为unsigned
,void srand(unsigned int seed);
参数的类型保留这3个最低有效位为0。unsigned seed
及其n
位(通常为32)现在具有少3
的“随机”位。按
prime > 2
而不是1000缩放可能有好处。“srand(time(0)* int_value))”是一种为每次执行获取不同值的好方法吗?
一种常见的替代方法是使用
srand()
进行初始化,使得在同一time()
(例如,同一秒)中启动的两个程序可能具有不同的种子,这种方法涉及使用其他“随机”源。无论使用什么源,最好使用 unsigned math而不是
|, &, *, /, ...
来^
它们。一些系统提供进程ID。
字符串
如果真正的用户输入发生在
srand()
之前,另一个有用的来源是查询clock()
。@selbie提供了一个获取变量地址的有用想法。该地址可以是固定的,也可以在每次程序运行时都不同。将其排它或-不会造成任何伤害,但可能会提供更多的“随机”位。
当然,各种系统提供比
srand(), rand()
更好的上级随机数功能。3j86kqsm2#
如果您没有安全问题,
time
和rand
作为随机数种子是完全合适的。请注意:time(0)
乘以1000没有意义。只是时间(0)或time(NULL)
这里有一些我很久以前写的随机数生成器的种子代码。它不一定是安全的或最好的。但它适用于Windows,Linux和Mac。
字符串
ajsxfq5m3#
与一个固定的数字相乘并不会使种子更随机。如果你在大约相同的时间启动两个程序,你仍然会得到相同的种子。
你可以使用一个可能具有更高分辨率的时钟来降低获得相同种子的风险:
字符串
或者使用一个真正的随机源来播种你的PRNG,在Linux上你有
/dev/random
或者更新的getrandom()
,你可以从中读取sizeof(unsigned)
字节来创建你的种子。lrpiutwd4#
您可以在PRNG种子中引入用户响应时间。
字符串
如果有用户交互,也可以使用
clock()
修改rand()
的值。t40tm48m5#
srand/rand
被认为是一个糟糕的随机数生成器。无论问题是什么,主要是因为第一个生成的值与种子耦合太紧密。看看这些第一个随机值(time(0),rand,RAND_MAX,计算的浮点数):字符串
差值小于您的预期。一个小的解决方法是(例如)只获取一些较低有效位:
型
然后,您将得到类似于:
型
然后
型