its*_*ode 14 c random algorithm
我已经看到很多关于这个特定主题的问题,但没有一个对我有任何答案,所以我想问这个问题.
我想在[-1,1]之间生成一个随机数.我怎么能这样做?
Jac*_*cob 18
使用 -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唯一的随机数.
Jon*_*ler 10
如果你拥有的只是标准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();
Run Code Online (Sandbox Code Playgroud)
请注意,手册说:
drand48()和erand48()函数应返回非负的,双精度的浮点值,均匀分布在区间[0.0,1.0]上.
如果您严格需要[-1.0,+1.0](而不是[-1.0,+1.0)),那么您将面临一个如何扩展范围的非常微妙的问题.
这些drand48()函数比典型的实现具有更多的随机性rand().但是,如果您需要加密随机性,则这些都不合适; 你需要寻找'密码强PRNG'(PRNG =伪随机数发生器).
我前面有一个类似的问题,并认为直接生成小数部分可能更有效.我做了一些搜索并遇到了一个有趣的快速浮点rand,它不使用浮点除法或乘法,或者int-> float cast可以通过对浮点内部表示的一些深入了解来完成:
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 );
}
Run Code Online (Sandbox Code Playgroud)
第一部分从[2 ^ 1,2 ^ 2]生成一个随机浮点数,减去3,你有[-1,1].对于某些应用程序/开发人员而言,这当然可能过于贴心,但这正是我所寻求的.这种机制适用于2宽度范围的任何范围.
首先,您需要C库函数rand().这是在stdlib.h头文件中,所以你应该把:
#include <stdlib.h>
Run Code Online (Sandbox Code Playgroud)
靠近代码的开头.rand()将生成一个介于零之间的随机整数,RAND_MAX因此除以它将RAND_MAX / 2给出一个介于0和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;
Run Code Online (Sandbox Code Playgroud)