如何在C语言中生成浮点随机数?(包括负数)
如何在C语言中生成浮点随机数?(包括负数)
一般来说,要从任意分布中生成随机数,首先需要生成均匀分布的随机数,然后将它们传递给累积分布函数的反函数。
例如,假设您想要在区间[-10.0, 10.0]上具有均匀分布的随机数,而您所拥有的只是[0.0, 1.0]范围内的随机数。在[-10.0, 10.0]上的均匀分布的累积分布函数为:
cdf(x) = 0.05 * x + 0.5 for x in [-10.0, 10.0]
icdf(y) = 20.0 * y - 10.0 for y in [0.0, 1.0]
如果你把x轴和y轴交换,就可以很容易地在纸上得到这个结果。
因此,要获得均匀分布在[-10.0, 10.0]上的随机数,你可以使用以下代码:
#include <stdlib.h>
// Returns uniformly distributed random numbers from [0.0, 1.0].
double uniform0to1Random() {
double r = random();
return r / ((double)RAND_MAX + 1);
}
// Returns uniformly distributed random numbers from [-10.0, 10.0].
double myRandom() {
return 20.0 * uniform0to1Random() - 10.0;
}
编辑:由于问题已经仅限于C语言:
这个页面非常有用:http://www.geekpedia.com/tutorial39_Random-Number-Generation.html
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
//use this first function to seed the random number generator,
//call this before any of the other functions
void initrand()
{
srand((unsigned)(time(0)));
}
//generates a psuedo-random float between 0.0 and 0.999...
float randfloat()
{
return rand()/(float(RAND_MAX)+1);
}
//generates a psuedo-random float between 0.0 and max
float randfloat(float max)
{
return randfloat()*max;
}
//generates a psuedo-random float between min and max
float randfloat(float min, float max)
{
if (min>max)
return randfloat()*(min-max)+max;
else
return randfloat()*(max-min)+min;
}
//generates a psuedo-random double between 0.0 and 0.999...
double randdouble()
{
return rand()/(double(RAND_MAX)+1);
}
//generates a psuedo-random double between 0.0 and max
double randdouble(double max)
{
return randdouble()*max;
}
//generates a psuedo-random double between min and max
double randdouble(double min, double max)
{
if (min>max)
return randdouble()*(min-max)+max;
else
return randdouble()*(max-min)+min;
}
int main()
{
for (int i=0; i<10; i++)
printf("%f\n", randdouble(-1,3));
}
2.360751
0.577532
2.132397
2.193760
2.646589
-0.209795
0.340891
2.072918
0.111099
1.215880
double
可以完成相同的任务时,使用float
通常是错误的 :-) - pmg以下内容将为您提供一个浮点数,范围在-max/2
到+max/2
之间:
float max = 5000;
float r = max * ((float)rand()/(float)RAND_MAX - 0.5);
float
和 double
,取决于 RAND_MAX
值,它可能会影响精度。由于不能保证它是2的幂,因此最好在这里也使用 double
(尾数52+1而不仅仅是23+1位),或者总体上在这里使用 double
以便不失去任何精度。然而,对于 rand()
或 RAND_MAX
中的任何一个操作数进行转换应该就足够了 - 另一个操作数随之被采纳。 - glglgl看一下 Boost.Random:
http://www.boost.org/doc/libs/1_47_0/doc/html/boost_random.html
你可以通过以下方式获取随机的浮点数值:
boost::mt19937 base_rng;
boost::uniform_01<> u01;
boost::variate_generator<boost::mt19937&, boost::uniform_01<> > rng(base_rng, u01);
rng(); // draws a random number
http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01617.html
您可以使用
rand() / (double)RAND_MAX /* 0 <= random number <= 1 */
rand() / (RAND_MAX + 1.0) /* 0 <= random number < 1 */
要生成一个介于0和1之间的随机数。
然后乘以您所需的范围,并加上初始值。
例如,要获取随机数0 <= X < 4.2
double tmp = rand() / (RAND_MAX + 1.0)
X = tmp * 4.2;
获取随机数 -21.1 <= X <= 37.5
double tmp = rand() / (double)RAND_MAX
X = tmp * (37.5 + 21.1);
X = X - 21.1;
http://www.gnu.org/s/gsl/manual/html_node/Random-number-generator-algorithms.html
即使由于许可问题无法使用它,它也应该为您提供一些要在 Google 上搜索的名称。 boost random 库(C++)使用延迟 Fibonacci 和 ranlux 算法来处理双精度和浮点数,因此它们可能是您的另一个选择。(方法不是 boost 库,因为它是 C++) 这些技术通常会给出 0 到 1 范围内的结果。通过使用R = rmin + v* (rmax-rmin)
公式,其中 v 在 0 到 1 范围内,您将得到 rmin -- rmax 中的 R
。int randNum = rand();
float floatRand = randNum/RAND_MAX;
floatRand是一个在[0,1]范围内的随机浮点数。然而,这种方法的分辨率受到RAND_MAX的限制。
[编辑]: 要获得负值,请生成另一个随机数,如果它大于RAND_MAX/2,则将前一个数乘以(-1)。
randNum
是 int
类型;RAND_MAX
是一个 "整数常量表达式"。将第一个除以第二个将始终评估为 0
。 - pmg这将生成随机[任何可表示的浮点数]:
#include <stdio.h>
float randfdev(void)
{
float tmp;
int fd = open("/dev/urandom",O_RDONLY);
read(fd,&tmp,sizeof tmp);
return tmp;
}
注意: