生成浮点随机值(也为负数)

时间:2011-11-02 10:21:11

标签: c random

如何在C中生成浮点随机值? (也是否定

8 个答案:

答案 0 :(得分:3)

一般来说,要从任意分布生成随机数,您首先要生成均匀的随机数,然后将它们传递给累积分布函数的反函数。

假设您想要在区间[-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]

这表示生成的随机数小于x的概率。逆是

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;
}

事实上,你不需要uniform0to1Random(),因为[0.0,1.0]已经有很多优秀的均匀随机数生成器(例如在boost库中)。

您可以使用该方法通过对逆累积分布进行采样来生成几乎任何所需概率分布的随机数,如上所示。

有关详细信息,请参阅http://en.wikipedia.org/wiki/Inverse_transform_sampling

答案 1 :(得分:2)

以下内容会为您提供-max/2+max/2之间的范围:

float max = 5000;
float r = max * ((float)rand()/(float)RAND_MAX - 0.5);

答案 2 :(得分:1)

修改由于问题仅针对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

(注意范围:-1..3)

答案 3 :(得分:0)

看看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

请注意,新的C ++标准现在提供随机数生成工具:

http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01617.html

答案 4 :(得分:0)

GNU科学图书馆有几种方法。

http://www.gnu.org/s/gsl/manual/html_node/Random-number-generator-algorithms.html

即使您因许可而无法使用它,也应该为您提供一些谷歌的名称。

增强随机库(C ++)使用滞后的斐波纳契和ranlux算法来实现双精度和浮点数,因此它们可能是您的另一种选择。 (方法不是boost库,因为它是C ++)

这些技巧通常会给出0到1范围内的结果。通过使用R = rmin + v* (rmax-rmin),其中v在0 - 1中,你将得到R in rmin - rmax

答案 5 :(得分:0)

您可以使用

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;

答案 6 :(得分:-1)

我所知道的最简单的方法:

int randNum = rand();
float floatRand = randNum/RAND_MAX;

floatRand是[0,1]中的随机浮点数。但是,此方法的分辨率受RAND_MAX ..

的限制

[编辑]: 得到负值,生成另一个随机数,如果它大于RAND_MAX / 2,则将前者乘以(-1)。

答案 7 :(得分:-1)

这将生成随机[任何可表示的浮点数]:

#include <stdio.h>

float randfdev(void)
    {
    float tmp;
    int fd = open("/dev/urandom",O_RDONLY);
    read(fd,&tmp,sizeof tmp);
    return tmp;
    }

注意:

  • 没有错误检查
  • 假设IEEE浮点数,但其他格式应该有效
  • 会产生NaN,次正规,无穷大等