如何在C中生成一个随机int ?

有没有一个函数生成一个随机int数在C?或者我必须使用第三方库?

2137749 次浏览

对于c, STL不存在。你必须调用rand,或者更好的是,random。它们在标准库头文件stdlib.h中声明。rand是POSIX, random是BSD规范函数。

randrandom之间的区别是random返回一个更有用的32位随机数,而rand通常返回一个16位数字。BSD manpage显示rand的低位是循环的和可预测的,因此rand对于较小的数字可能是无用的。

STL是c++,不是C,所以我不知道你想要什么。然而,如果你想使用C语言,有rand()srand()函数:

int rand(void);


void srand(unsigned seed);

它们都是ANSI c的一部分。还有random()函数:

long random(void);

但据我所知,random()不是标准的ANSI c。第三方库可能不是一个坏主意,但这完全取决于你真正需要生成的数字有多随机。

您希望使用rand()。注意(非常重要的):确保为rand函数设置种子。如果你没有,你的随机数是并非完全随机。这是非常、非常、非常重要的。值得庆幸的是,您通常可以使用系统滴答计时器和日期的某种组合来获得良好的种子。

<stdlib.h>中的rand()函数返回一个介于0和RAND_MAX之间的伪随机整数。您可以使用srand(unsigned int seed)来设置种子。

通常使用%操作符和rand()操作符来获得不同的范围(但请记住,这在一定程度上破坏了一致性)。例如:

/* random int between 0 and 19 */
int r = rand() % 20;

如果你真的关心一致性,你可以这样做:

/* Returns an integer in the range [0, n).
*
* Uses rand(), and so is affected-by/affects the same seed.
*/
int randint(int n) {
if ((n - 1) == RAND_MAX) {
return rand();
} else {
// Supporting larger values for n would requires an even more
// elaborate implementation that combines multiple calls to rand()
assert (n <= RAND_MAX)


// Chop off all of the values that would cause skew...
int end = RAND_MAX / n; // truncate skew
assert (end > 0);
end *= n;


// ... and ignore results from rand() that fall above that limit.
// (Worst case the loop condition should succeed 50% of the time,
// so we can expect to bail out of this loop pretty quickly.)
int r;
while ((r = rand()) >= end);


return r % n;
}
}

FWIW,答案是肯定的,有一个stdlib.h函数叫做rand;此函数主要针对速度和分布进行调优,而不是针对不可预测性。几乎所有语言和框架的内置随机函数都默认使用这个函数。还有“加密”随机数生成器,它们的可预测性要低得多,但运行速度要慢得多。在任何类型的与安全相关的应用程序中都应该使用它们。

看看以撒(间接,移位,累积,添加和计数)。它是均匀分布的,平均循环长度为2^8295。

请注意:为了安全,不要使用rand()。如果你需要一个加密安全的数字,可以选择请看这个答案

#include <time.h>
#include <stdlib.h>


srand(time(NULL));   // Initialization, should only be called once.
int r = rand();      // Returns a pseudo-random integer between 0 and RAND_MAX.

在Linux上,您可能更喜欢使用随机和srandom

如果您需要比stdlib提供的质量更好的伪随机数,请查看< >强梅森素数捻线机< / >强。它也更快。示例实现有很多,例如在这里

我们来看看这个。首先,我们使用srand()函数来为随机器播种。基本上,计算机可以根据输入给srand()的数字生成随机数。如果你给出相同的种子值,那么每次都会生成相同的随机数。

因此,我们必须用一个总是在变化的值来给随机化器播种。为此,我们使用time()函数将当前时间的值提供给它。

现在,当我们调用rand()时,每次都会产生一个新的随机数。

    #include <stdio.h>


int random_number(int min_num, int max_num);


int main(void)
{
printf("Min : 1 Max : 40 %d\n", random_number(1,40));
printf("Min : 100 Max : 1000 %d\n",random_number(100,1000));
return 0;
}


int random_number(int min_num, int max_num)
{
int result = 0, low_num = 0, hi_num = 0;


if (min_num < max_num)
{
low_num = min_num;
hi_num = max_num + 1; // include max_num in output
} else {
low_num = max_num + 1; // include max_num in output
hi_num = min_num;
}


srand(time(NULL));
result = (rand() % (hi_num - low_num)) + low_num;
return result;
}

试试这个,我把上面已经提到的一些概念放在一起:

/*
Uses the srand() function to seed the random number generator based on time value,
then returns an integer in the range 1 to max. Call this with random(n) where n is an integer, and you get an integer as a return value.
*/


int random(int max) {
srand((unsigned) time(NULL));
return (rand() % max) + 1;
}

rand()是生成随机数最方便的方法。

你也可以从任何在线服务如random.org捕获随机数。

#include <stdio.h>
#include <dos.h>


int random(int range);


int main(void)
{
printf("%d", random(10));
return 0;
}


int random(int range)
{
struct time t;
int r;


gettime(&t);
r = t.ti_sec % range;
return r;
}

这是一个在你选择的两个数字之间得到一个随机数的好方法。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


#define randnum(min, max) \
((rand() % (int)(((max) + 1) - (min))) + (min))


int main()
{
srand(time(NULL));


printf("%d\n", randnum(1, 70));
}

第一次输出:39

第二次输出:61

第三次输出:65

您可以将randnum之后的值更改为您选择的任何数字,它将在这两个数字之间为您生成一个随机数。

有人很好地解释了为什么使用rand()在给定范围内生成均匀分布的随机数是一个坏主意,我决定看看输出到底有多倾斜。我的测试案例是公平掷骰子。下面是C代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main(int argc, char *argv[])
{
int i;
int dice[6];


for (i = 0; i < 6; i++)
dice[i] = 0;
srand(time(NULL));


const int TOTAL = 10000000;
for (i = 0; i < TOTAL; i++)
dice[(rand() % 6)] += 1;


double pers = 0.0, tpers = 0.0;
for (i = 0; i < 6; i++) {
pers = (dice[i] * 100.0) / TOTAL;
printf("\t%1d  %5.2f%%\n", dice[i], pers);
tpers += pers;
}
printf("\ttotal:  %6.2f%%\n", tpers);
}

这是它的输出:

 $ gcc -o t3 t3.c
$ ./t3
1666598  16.67%
1668630  16.69%
1667682  16.68%
1666049  16.66%
1665948  16.66%
1665093  16.65%
total:  100.00%
$ ./t3
1667634  16.68%
1665914  16.66%
1665542  16.66%
1667828  16.68%
1663649  16.64%
1669433  16.69%
total:  100.00%

我不知道你需要你的随机数有多统一,但上面的看起来足够统一,满足大多数需求。

编辑:用比time(NULL)更好的东西初始化PRNG是个好主意。

#include <stdio.h>
#include <stdlib.h>


void main()
{
int visited[100];
int randValue, a, b, vindex = 0;


randValue = (rand() % 100) + 1;


while (vindex < 100) {
for (b = 0; b < vindex; b++) {
if (visited[b] == randValue) {
randValue = (rand() % 100) + 1;
b = 0;
}
}


visited[vindex++] = randValue;
}


for (a = 0; a < 100; a++)
printf("%d ", visited[a]);
}

标准的C函数是rand()。它可以用来发纸牌,但很糟糕。rand()的许多实现通过一个简短的数字列表循环,低位的周期更短。一些程序调用rand()的方式很糟糕,计算一个传递给srand()的好种子很困难。

在C语言中生成随机数的最佳方法是使用第三方库,如OpenSSL。例如,

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>


/* Random integer in [0, limit) */
unsigned int random_uint(unsigned int limit) {
union {
unsigned int i;
unsigned char c[sizeof(unsigned int)];
} u;


do {
if (!RAND_bytes(u.c, sizeof(u.c))) {
fprintf(stderr, "Can't get random bytes!\n");
exit(1);
}
} while (u.i < (-limit % limit)); /* u.i < (2**size % limit) */
return u.i % limit;
}


/* Random double in [0.0, 1.0) */
double random_double() {
union {
uint64_t i;
unsigned char c[sizeof(uint64_t)];
} u;


if (!RAND_bytes(u.c, sizeof(u.c))) {
fprintf(stderr, "Can't get random bytes!\n");
exit(1);
}
/* 53 bits / 2**53 */
return (u.i >> 11) * (1.0/9007199254740992.0);
}


int main() {
printf("Dice: %d\n", (int)(random_uint(6) + 1));
printf("Double: %f\n", random_double());
return 0;
}

为什么有这么多代码?其他语言,如Java和Ruby,都有用于随机整数或浮点数的函数。OpenSSL只提供随机字节,因此我尝试模拟Java或Ruby如何将它们转换为整数或浮点数。

对于整数,我们希望避免使用模的偏见。假设我们从rand() % 10000中得到一些随机的4位整数,但是rand()只能返回0到32767(就像在Microsoft Windows中那样)。0到2767之间的每个数字出现的频率要高于2768到9999之间的每个数字。为了消除偏差,我们可以在值低于2768时重试rand(),因为从2768到32767的30000个值统一映射到从0到9999的10000个值。

对于浮点数,我们需要53个随机位,因为double包含53位精度(假设它是IEEE双精度)。如果我们使用超过53位,就会产生舍入偏差。有些程序员编写类似rand() / (double)RAND_MAX的代码,但是rand()可能只返回31位,或者在Windows中只返回15位。

OpenSSL的RAND_bytes()本身就是种子,也许可以通过阅读Linux中的/dev/urandom来实现。如果我们需要很多随机数,从/dev/urandom中读取它们会很慢,因为它们必须从内核中复制。允许OpenSSL从种子中生成更多的随机数会更快。

更多关于随机数的内容:

如果您的系统支持arc4random系列函数,我建议使用这些函数代替标准的rand函数。

arc4random系列包括:

uint32_t arc4random(void)
void arc4random_buf(void *buf, size_t bytes)
uint32_t arc4random_uniform(uint32_t limit)
void arc4random_stir(void)
void arc4random_addrandom(unsigned char *dat, int datlen)

arc4random返回随机的32位无符号整数。

arc4random_buf将随机内容放在参数buf : void *中。内容的数量由bytes : size_t参数决定。

arc4random_uniform返回一个随机的32位无符号整数,它遵循规则:0 <= arc4random_uniform(limit) < limit,其中limit也是一个32位无符号整数。

arc4random_stir/dev/urandom读取数据并将数据传递给arc4random_addrandom以额外随机化它的内部随机数池。

arc4random_addrandomarc4random_stir使用,根据传递给它的数据填充它的内部随机数池。

如果你没有这些函数,但你在Unix上,那么你可以使用下面的代码:

/* This is C, not C++ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h> /* exit */
#include <stdio.h> /* printf */


int urandom_fd = -2;


void urandom_init() {
urandom_fd = open("/dev/urandom", O_RDONLY);


if (urandom_fd == -1) {
int errsv = urandom_fd;
printf("Error opening [/dev/urandom]: %i\n", errsv);
exit(1);
}
}


unsigned long urandom() {
unsigned long buf_impl;
unsigned long *buf = &buf_impl;


if (urandom_fd == -2) {
urandom_init();
}


/* Read sizeof(long) bytes (usually 8) into *buf, which points to buf_impl */
read(urandom_fd, buf, sizeof(long));
return buf_impl;
}

urandom_init函数打开/dev/urandom设备,并将文件描述符放在urandom_fd中。

urandom函数基本上与调用rand相同,只是更安全,它返回long(很容易更改)。

但是,/dev/urandom可能有点慢,所以建议将它用作不同随机数生成器的种子。

如果您的系统没有/dev/urandom,但是/dev/random或类似的文件,那么您可以简单地在urandom_init中更改传递到open的路径。urandom_initurandom中使用的调用和api(我相信)是POSIX兼容的,因此,即使不是所有POSIX兼容的系统,也应该在大多数系统上工作。

注意:如果可用熵不足,从/dev/urandom读取将不会阻塞,因此在这种情况下生成的值可能是密码不安全的。如果您担心这一点,那么使用/dev/random,如果熵不足,它总是会阻塞。

如果您在另一个系统(即。),然后使用rand或一些内部Windows特定平台依赖的不可移植API。

包装器函数为urandomrand,或arc4random调用:

#define RAND_IMPL /* urandom(see large code block) | rand | arc4random */


int myRandom(int bottom, int top){
return (RAND_IMPL() % (top - bottom)) + bottom;
}

希望这比仅仅使用srand(time(NULL))更随机一些。

#include <time.h>
#include <stdio.h>
#include <stdlib.h>


int main(int argc, char **argv)
{
srand((unsigned int)**main + (unsigned int)&argc + (unsigned int)time(NULL));
srand(rand());


for (int i = 0; i < 10; i++)
printf("%d\n", rand());
}

我的极简解决方案应该适用于范围[min, max)的随机数。在调用函数之前使用srand(time(NULL))

int range_rand(int min_num, int max_num) {
if (min_num >= max_num) {
fprintf(stderr, "min_num is greater or equal than max_num!\n");
}
return min_num + (rand() % (max_num - min_num));
}

如果你需要安全的随机字符或整数:

正如在如何在各种编程语言中安全地生成随机数中所述,您将需要执行以下操作之一:

例如:

#include "sodium.h"


int foo()
{
char myString[32];
uint32_t myInt;


if (sodium_init() < 0) {
/* panic! the library couldn't be initialized, it is not safe to use */
return 1;
}




/* myString will be an array of 32 random bytes, not null-terminated */
randombytes_buf(myString, 32);


/* myInt will be a random number between 0 and 9 */
myInt = randombytes_uniform(10);
}

randombytes_uniform()是加密安全和无偏的。

在我最近的应用程序中,我遇到了一个严重的伪随机数生成器问题:我多次通过Python脚本调用我的C程序,并使用以下代码作为种子:

srand(time(NULL))

然而,由于:

  • rand将生成相同的伪随机序列,在srand中给出相同的种子(见man srand);
  • 如前所述,时间函数每秒只会改变:如果应用程序在同一秒内运行多次,time每次将返回相同的值。
我的程序生成了相同的数字序列。 你可以做三件事来解决这个问题:

  1. 混合时间输出与一些其他信息改变运行(在我的应用程序中,输出名称):

    srand(time(NULL) | getHashOfString(outputName))
    

    我使用djb2作为我的哈希函数。

  2. 提高时间分辨率在我的平台上,clock_gettime是可用的,所以我使用它:

    #include<time.h>
    struct timespec nanos;
    clock_gettime(CLOCK_MONOTONIC, &nanos)
    srand(nanos.tv_nsec);
    
  3. 两种方法一起使用:

    #include<time.h>
    struct timespec nanos;
    clock_gettime(CLOCK_MONOTONIC, &nanos)
    srand(nanos.tv_nsec | getHashOfString(outputName));
    
选项3确保你(据我所知)最好的种子随机性,但它可能只会在非常快速的应用中产生差异。 在我看来,选项2是一个安全的赌注

C程序生成9到50之间的随机数

#include <time.h>
#include <stdlib.h>


int main()
{
srand(time(NULL));
int lowerLimit = 10, upperLimit = 50;
int r =  lowerLimit + rand() % (upperLimit - lowerLimit);
printf("%d", r);
}

一般来说,我们可以在lowerLimit和upperLimit-1之间生成一个随机数

例如lowerLimit是包含的或说r∈[lowerLimit, upperLimit)

在现代的x86_64 cpu上,您可以通过_rdrand64_step()使用硬件随机数生成器

示例代码:

#include <immintrin.h>


uint64_t randVal;
if(!_rdrand64_step(&randVal)) {
// Report an error here: random number generation has failed!
}
// If no error occured, randVal contains a random 64-bit number

尽管这里所有人都建议使用rand(),但除非迫不得已,否则你不会想使用rand() !rand()生成的随机数通常非常糟糕。引用Linux手册页:

Linux C库中的rand()srand()版本使用与random(3)srandom(3)相同的随机数生成器,因此低阶位应该与高阶位一样随机。但是,在旧的rand()实现上,以及在不同系统上的当前实现上,低阶比特比高阶比特随机得多。当需要良好的随机性时,不要在旨在可移植的应用程序中使用此函数。(# EYZ6)

关于可移植性,random()也由POSIX标准定义了很长一段时间。rand()更老,它已经出现在第一个POSIX.1规范(IEEE Std 1003.1-1988)中,而random()首次出现在POSIX.1-2001 (IEEE Std 1003.1-2001)中,然而当前的POSIX标准已经是POSIX.1-2008 (IEEE Std 1003.1-2008),仅在一年前收到了更新(IEEE Std 1003.1-2008, 2016版)。所以我认为random()是非常可移植的。

POSIX.1-2001还引入了lrand48()mrand48()函数,在这里看到的:

此函数族应使用线性同余算法和48位整数算术生成伪随机数。

一个非常好的伪随机源是arc4random()函数,它在许多系统上都可用。不是任何官方标准的一部分,在1997年左右出现在BSD中,但你可以在Linux和macOS/iOS等系统上找到它。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>


//generate number in range [min,max)
int random(int min, int max){
int number = min + rand() % (max - min);
return number;
}


//Driver code
int main(){
srand(time(NULL));
for(int i = 1; i <= 10; i++){
printf("%d\t", random(10, 100));
}
return 0;
}

对于Linux C应用程序:

这是我根据上面的答案重新编写的代码,它遵循我的C代码实践并返回任意大小的随机缓冲区(具有适当的返回代码等)。确保在程序开始时调用urandom_open()一次。

int gUrandomFd = -1;


int urandom_open(void)
{
if (gUrandomFd == -1) {
gUrandomFd = open("/dev/urandom", O_RDONLY);
}


if (gUrandomFd == -1) {
fprintf(stderr, "Error opening /dev/urandom: errno [%d], strerrer [%s]\n",
errno, strerror(errno));
return -1;
} else {
return 0;
}
}




void urandom_close(void)
{
close(gUrandomFd);
gUrandomFd = -1;
}




//
// This link essentially validates the merits of /dev/urandom:
// http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
//
int getRandomBuffer(uint8_t *buf, int size)
{
int ret = 0; // Return value


if (gUrandomFd == -1) {
fprintf(stderr, "Urandom (/dev/urandom) file not open\n");
return -1;
}


ret = read(gUrandomFd, buf, size);


if (ret != size) {
fprintf(stderr, "Only read [%d] bytes, expected [%d]\n",
ret, size);
return -1;
} else {
return 0;
}
}

您可以使用悬空指针的概念。

指向已删除(或释放)内存位置的指针称为悬浮指针。

它将在打印时显示随机值。

下面是我的方法(围绕rand()的包装):

我还缩放到允许最小值为INT_MIN和最大值为INT_MAX的情况,这通常不可能单独使用rand(),因为它返回的值从0RAND_MAX,包括(1/2的范围)。

像这样使用它:

const int MIN = 1;
const int MAX = 1024;
// Get a pseudo-random number between MIN and MAX, **inclusive**.
// Seeding of the pseudo-random number generator automatically occurs
// the very first time you call it.
int random_num = utils_rand(MIN, MAX);

定义和氧描述:

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>


/// \brief      Use linear interpolation to rescale, or "map" value `val` from range
///             `in_min` to `in_max`, inclusive, to range `out_min` to `out_max`, inclusive.
/// \details    Similar to Arduino's ingenious `map()` function:
///             https://www.arduino.cc/reference/en/language/functions/math/map/
///
/// TODO(gabriel): turn this into a gcc statement expression instead to prevent the potential for
/// the "double evaluation" bug. See `MIN()` and `MAX()` above.
#define UTILS_MAP(val, in_min, in_max, out_min, out_max) \
(((val) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min))


/// \brief      Obtain a pseudo-random integer value between `min` and `max`, **inclusive**.
/// \details    1. If `(max - min + 1) > RAND_MAX`, then the range of values returned will be
///             **scaled** to the range `max - min + 1`, and centered over the center of the
///             range at `(min + max)/2`. Scaling the numbers means that in the case of scaling,
///             not all numbers can even be reached. However, you will still be assured to have
///             a random distribution of numbers across the full range.
///             2. Also, the first time per program run that you call this function, it will
///             automatically seed the pseudo-random number generator with your system's
///             current time in seconds.
/// \param[in]  min         The minimum pseudo-random number you'd like, inclusive. Can be positive
///                         OR negative.
/// \param[in]  max         The maximum pseudo-random number you'd like, inclusive. Can be positive
///                         OR negative.
/// \return     A pseudo-random integer value between `min` and `max`, **inclusive**.
int utils_rand(int min, int max)
{
static bool first_run = true;
if (first_run)
{
// seed the pseudo-random number generator with the seconds time the very first run
time_t time_now_sec = time(NULL);
srand(time_now_sec);
first_run = false;
}


int range = max - min + 1;
int random_num = rand();  // random num from 0 to RAND_MAX, inclusive


if (range > RAND_MAX)
{
static_assert(
sizeof(long int) > sizeof(int),
"This must be true or else the below mapping/scaling may have undefined overflow "
"and not work properly. In such a case, try casting to `long long int` instead of "
"just `long int`, and update this static_assert accordingly.");


random_num = UTILS_MAP((long int)random_num, (long int)0, (long int)RAND_MAX, (long int)min,
(long int)max);
return random_num;
}


// This is presumably a faster approach than the map/scaling function above, so do this faster
// approach below whenever you don't **have** to do the more-complicated approach above.
random_num %= range;
random_num += min;


return random_num;
}


参见:

  1. [我在上面的答案中发现了这个问题,但它显然是非常相关的,他们做的事情和我对非缩放范围的情况做的一样]我如何从rand()得到一个特定范围的数字?
  2. [我需要研究和阅读这个答案更多仍然-似乎有一些好的观点,保持良好的随机性不使用模量单独]我如何从rand()得到一个特定的数字范围?
    1. http://c-faq.com/lib/randrange.html

如果您需要128个安全随机位,符合RFC 1750的解决方案是读取已知可以生成可用熵位的硬件源(例如旋转磁盘)。更好的是,好的实现应该通过重新映射或删除输出,使用混合函数de-skew来组合多个源的输出分布。

如果你需要更多的比特,遵从的事情是开始128安全随机位序列,拉伸到所需的长度,将其映射到人类可读的文本,等等。

如果你想在C中生成一个安全的随机数,我将遵循这里的源代码:

https://wiki.sei.cmu.edu/confluence/display/c/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers

注意,对于Windows bbcryptgenrandom是使用的,而不是CryptGenRandom,在过去的20年里已经变得不安全。您可以亲自确认BCryptGenRandom符合RFC 1750。

对于posix兼容的操作系统,例如Ubuntu (Linux的一种风格),您可以简单地从/dev/urandom/dev/random读取,这是一个类似文件的接口,用于以符合RFC 1750的方式组合多个源来生成比特熵的设备。您可以从这些“文件”中读取所需数量的字节。使用readfread,就像使用任何其他文件一样,但请注意,从/dev/random读取将阻塞,直到有足够的新熵位可用,而/dev/urandom则不会,这可能是一个安全问题。你可以通过检查可用熵池的大小来解决这个问题,或者我从entropy_avail中读取,或者使用ioctl

与此相关的特定于# eyz5的函数(应该在大多数Linux环境中都可以找到)是random(),或者您可能对其线程安全版本random_r()感兴趣。在将random_r()传递给struct random_data之前,必须使用initstate_r()初始化struct random_data

下面是一个快速的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


void xxx (void) {
unsigned int seed = (unsigned int) time(NULL);
char rnd_state[17] = {0};
struct random_data rnd_st_buf = {0};
initstate_r(seed, &rnd_state[0], 17, &rnd_st_buf);
for(size_t idx = 0; idx < 8; idx++) {
int32_t rnd_int = 0;
char rnd_seq_str[6] = {0};
random_r(&rnd_st_buf, &rnd_int);
memcpy((char *)&rnd_seq_str[0], (char *)&rnd_int, 4);
printf("random number : 0x%08x,  \n", rnd_int);
}
}

你可以生成随机字符,然后将它们视为int:

#include <stdlib.h>
#include <stdio.h>


typedef double rand_type; // change double to int


rand_type my_rand() {
char buff[sizeof(rand_type)];
for (size_t i = 0 ; i < sizeof(rand_type) ; ++i)
buff[i] = (char) rand();
return *(rand_type *) buff;
}


int main() {
int i ; // srand as you want
for (i = 0 ; i < 10 ; ++i)
printf("%g\n", my_rand()); // change %g to %d
return 0 ;
}

你也可以使用mathgl库#include <mgl2/mgl_cf.h>(虽然首先你需要安装,我自己通过MSYS2安装)函数mgl_rnd()。它也有均匀分布,高斯分布等等。这是ez的用法。但我不知道它的特点。