rand-31
这是对您的程序的改编,它显示了正在发生的事情的更多细节:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int x = ((unsigned int)time(NULL));
srand((unsigned int)x);
int r1 = rand();
int y = ((double)r1/(double)(RAND_MAX)*10);
int r2 = rand();
int z = ((double)r2/(double)(RAND_MAX)*10);
printf("Time %d\n", x);
printf("Random 1: %d\n", r1);
printf("Number y: %d\n", y);
printf("Random 2: %d\n", r2);
printf("Number z: %d\n", z);
return 0;
}
它独立于计算捕获两个rand() 调用的结果,以便可以打印它们。它还确保传递给time() 的值与打印的值相同,尽管它们不同的可能性非常小。
当我运行它几次时,我得到了输出:
Time 1508694677
Random 1: 1292016210
Number y: 6
Random 2: 1709286653
Number z: 7
Time 1508694685
Random 1: 1292150666
Number y: 6
Random 2: 1821604998
Number z: 8
Time 1508694701
Random 1: 1292419578
Number y: 6
Random 2: 2046241688
Number z: 9
Time 1508694841
Random 1: 1294772558
Number y: 6
Random 2: 790587255
Number z: 3
如您所见,rand() 返回的值是不同的,但差别不大,因此计算的值并没有那么不同。
rand-23
一个简单的升级选项是使用drand48() 函数,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int x = ((unsigned int)time(NULL));
srand48((unsigned int)x);
int r1 = lrand48();
int y = ((double)r1/(double)(RAND_MAX)*10);
int r2 = lrand48();
int z = ((double)r2/(double)(RAND_MAX)*10);
printf("RAND_MAX: %d\n", RAND_MAX);
printf("Time: %d\n", x);
printf("Random 1: %d\n", r1);
printf("Number y: %d\n", y);
printf("Random 2: %d\n", r2);
printf("Number z: %d\n", z);
return 0;
}
代码打印RAND_MAX主要是为了表明它与lrand48()返回的值范围兼容,据记载它返回的值在0..2范围内31- 1.
这会产生不同且可以说是更好的结果:
RAND_MAX: 2147483647
Time: 1508695069
Random 1: 705270938
Number y: 3
Random 2: 1758232243
Number z: 8
RAND_MAX: 2147483647
Time: 1508695074
Random 1: 1465504939
Number y: 6
Random 2: 733780153
Number z: 3
RAND_MAX: 2147483647
Time: 1508695080
Random 1: 1948289010
Number y: 9
Random 2: 1222424564
Number z: 5
rand-13
或者,您可以按照 macOS 文档中的说明进行操作,然后切换到 arc4random()。该链接指向“旧版”XCode 5 文档,但功能最近没有改变。
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int x = ((unsigned int)time(NULL));
int r1 = arc4random_uniform(INT_MAX);
int y = ((double)r1/(double)(RAND_MAX)*10);
int r2 = arc4random_uniform(INT_MAX);
int z = ((double)r2/(double)(RAND_MAX)*10);
printf("INT_MAX: %d\n", INT_MAX);
printf("RAND_MAX: %d\n", RAND_MAX);
printf("Time: %d\n", x);
printf("Random 1: %d\n", r1);
printf("Number y: %d\n", y);
printf("Random 2: %d\n", r2);
printf("Number z: %d\n", z);
return 0;
}
这使用arc4random_uniform() 生成一个0..INT_MAX 范围内的值,与生成的其他函数的范围相同。没有 srand() 与 arc4random() 系列函数的类似物。
示例运行:
INT_MAX: 2147483647
RAND_MAX: 2147483647
Time: 1508695894
Random 1: 938614006
Number y: 4
Random 2: 851262647
Number z: 3
INT_MAX: 2147483647
RAND_MAX: 2147483647
Time: 1508695900
Random 1: 1332829945
Number y: 6
Random 2: 386007903
Number z: 1
INT_MAX: 2147483647
RAND_MAX: 2147483647
Time: 1508695913
Random 1: 1953583540
Number y: 9
Random 2: 1273643162
Number z: 5
rand-83
请注意,如果您想要一个介于 0 和 10 之间的随机整数,那么您应该直接使用 arc4random_uniform(10) 而不要进行计算。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int x = ((unsigned int)time(NULL));
int y = arc4random_uniform(10);
int z = arc4random_uniform(10);
printf("Time: %d\n", x);
printf("Number y: %d\n", y);
printf("Number z: %d\n", z);
return 0;
}
示例输出:
Time: 1508696162
Number y: 5
Number z: 3
Time: 1508696163
Number y: 7
Number z: 5
Time: 1508696165
Number y: 3
Number z: 8
arc4random() et al 的另一个优势体现在我设法在一秒钟内运行该程序 3 次。对于其他生成器,由于使用相同的种子,它们会产生相同的结果。
$ rand-83;rand-83;rand-83
Time: 1508696213
Number y: 4
Number z: 0
Time: 1508696213
Number y: 0
Number z: 1
Time: 1508696213
Number y: 9
Number z: 6
$
$ rand-31;rand-31;rand-31
Time 1508696334
Random 1: 1319865409
Number y: 6
Random 2: 1619339200
Number z: 7
Time 1508696334
Random 1: 1319865409
Number y: 6
Random 2: 1619339200
Number z: 7
Time 1508696334
Random 1: 1319865409
Number y: 6
Random 2: 1619339200
Number z: 7
$
JFTR:在运行 macOS High Sierra 10.13 的 MacBook Pro 上编译的代码。我使用 GCC 7.2.0(而不是 XCode 9)来编译,但是系统库——它是这里的关键库。