我看到的SO这个特定主题的许多问题,但他们都没有给我任何答复,所以我想提出这个问题的。
我想产生[1,1]之间的随机数。 我怎样才能做到这一点?
我看到的SO这个特定主题的许多问题,但他们都没有给我任何答复,所以我想提出这个问题的。
我想产生[1,1]之间的随机数。 我怎样才能做到这一点?
使用-1+2*((float)rand())/RAND_MAX
rand()
范围内的整数,生成[0,RAND_MAX]
包容因此, ((float)rand())/RAND_MAX
返回一个浮点数[0,1]
我们从随机数[-1,1]
通过将其添加到-1
。
编辑:(添加注释部分的相关部分)
在此方法的局限性:
((float)rand())/RAND_MAX
返回一个百分比(从0到1的一小部分)。 如此以来之间-1到1的范围是2点的整数,我乘上分数为2,然后将它添加到你想要的最低数目,-1。 这也告诉你关于你的随机数的质量,因为你只会有RAND_MAX
独特的随机数。
如果你已经是标准C库,那么其他人的回答是明智的。 如果你有POSIX的功能提供给您,请考虑使用drand48()系列函数。 特别是:
#define _XOPEN_SOURCE 600 /* Request non-standard functions */
#include <stdlib.h>
double f = +1.0 - 2.0 * drand48();
double g = -1.0 + 2.0 * drand48();
请注意,手册上说:
所述drand48()和erand48()函数将返回非负,双精度浮点值,均匀地分布在区间[0.0,1.0)。
如果你需要严格[-1.0,+1.0]
相对于[-1.0,+1.0)
那么你就面临着如何扩大范围非常微妙的问题。
该drand48()
函数给你相当多的随机性比典型的实施rand()
但是,如果你需要加密的随机性,这些都不是合适的; 你需要寻找“保密性强的PRNG”器(PRNG =伪随机数生成器)。
我有一个类似的问题而回,并认为这可能是更有效的,只是直接产生的小数部分。 我做了一些搜索和跨不使用浮点乘除或内部- >浮动投可以与一些做了一个有趣的快速浮点兰特来到成竹在胸浮点数的内部表示的:
float sfrand( void )
{
unsigned int a=(rand()<<16)|rand(); //we use the bottom 23 bits of the int, so one
//16 bit rand() won't cut it.
a=(a&0x007fffff) | 0x40000000;
return( *((float*)&a) - 3.0f );
}
第一部分产生从[2 ^ 1,2 ^ 2)的随机浮点数,减去3和你有[-1,1)。 当然,这可能是某些应用程序/开发者太亲密,但它正是我一直在寻找。 这种机制运作良好,因为这是2宽的功率的任何范围。
首先,你需要的C库函数rand()
这是stdlib.h
的头文件,所以你应该把:
#include <stdlib.h>
靠近你的代码的开头。 rand()
将产生零和之间的随机整数RAND_MAX
所以将其除以RAND_MAX / 2
会给你零和2(含)之间的一个数字。 减去一个,而你在-1到1你的目标范围内。
但是,如果简单地做int n = rand() / (RAND_MAX / 2)
你会发现你没有得到你所期望的答案。 这是因为两者rand()
和RAND_MAX / 2
是整数,因此使用整数运算。 为了阻止这种情况发生,有些人使用浮动演员,但我会建议由乘以避免铸件1.0
。
你也应该使用种子的随机数发生器srand()
的功能。 为了每次得到不同的结果,人们往往种子基于时钟时间发生器,通过做srand(time(0))
因此,总体而言,我们有:
#include <stdlib.h>
srand(time(0);
double r = 1.0 * rand() / (RAND_MAX / 2) - 1;
而接受的答案是在许多情况下细,就会留下了“每隔数”,因为它是扩大的范围已经离散值由2以覆盖[-1,1]的时间间隔。 以类似的方式,如果你有一个随机数发生器,它可以生成[0,10]一个整数,你想产生[0,20],简单地乘以2将涵盖范围,但不能涵盖范围(它会离开了所有的奇数)。
它可能有足够的细晶粒您的需求,但确实有这个缺点,这可能是在许多应用统计学显著(和有害的) - 特别是蒙特卡罗模拟和系统,对初始条件的敏感依赖性。
这是能够从-1到1之间产生任何表示的浮点数应该依靠生成序列A1.A2 A3 A4 A5 ...直到你的浮点精度的极限是能够的唯一途径的方法产生任何可能的浮动范围。 (即实数的定义如下)
从“C标准库”
int rand(void)
-返回范围伪随机数0
至RAND_MAX
RAND_MAX
-通过返回最大值rand()
所以:
rand()
将在范围返回一个伪随机数0
至RAND_MAX
rand() / RANDMAX
将在范围返回一个伪随机数0
至1
2*( rand() / RANDMAX )
将在范围返回一个伪随机数0
至2
2*( rand() / RANDMAX ) -1
将在范围返回一个伪随机数-1
至1
正如其他已经指出的,任何尝试简单地从[0,RAND_MAX]变换的范围内的“兰特()”功能到所需的[-1,+ 1]将产生一个随机数发生器,只能产生一组离散的浮动 - 点值。 对于浮点发生器这些值的密度可能是在一些应用中不足(如果RAND_MAX的实现所定义的值是不足够大)。 如果这是一个问题,人们可以通过指数地使用两个或更多增加上述密度“兰特()”调用,而不是一个。
例如,通过两个连续呼叫的结果结合到“兰特()”可以得到在[(RAND_MAX + 1)^ 2 0, - 1]的伪随机数范围
#define RAND_MAX2 ((RAND_MAX + 1ul) * (RAND_MAX + 1) - 1)
unsigned long r2 = (unsigned long) rand() * (RAND_MAX + 1) + rand();
后来用同样的方法将它转变成一个浮点数在[-1,+ 1]的范围
double dr2 = r2 * 2.0 / RAND_MAX2 - 1;
通过使用该方法可以堆积许多“兰特()”调用必要,保持整数溢出眼睛,当然。
作为一个侧面说明,结合连续的这种方法“兰特()”调用不会产生非常高品质的伪随机数生成器,但它可能会很好地工作的多种用途。