在使用Apple Xcode时,下面的C程序将始终返回y的5,而z将返回一个随机数,即使它们有相同的表达式。你能找出这种行为的原因吗?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int x,y,z;
srand((unsigned int)time(NULL));
x = ((unsigned int)time(NULL));
y=((double)rand()/(double)(RAND_MAX)*10);
z=((double)rand()/(double)(RAND_MAX)*10);
printf("Time %d\n", x);
printf("\n");
printf("Number y %d\n", y);
printf("\n");
printf("Number z %d\n", z);
printf("\n");
return 0;
}
最佳答案
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()
返回的值的范围兼容,而rand-13
返回的值的范围是0..231-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
arc4random()
或者,您也可以按照macOS文档的说明进行操作,然后切换到
arc4random_uniform()
。链接指向“遗留”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;
}
这将使用
srand()
在0..INT_MAX范围内生成一个值,该范围与生成的其他函数相同。没有类似于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
当我设法在一秒钟内运行程序3次时,
arc4random()
等的另一个优点就显示出来了。对于其他生成器,由于使用了相同的种子,这些生成器将产生相同的结果。$ 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)进行编译,但是系统库-而且它是这里的关键库。
关于c - Xcode中rand()的奇怪行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46877089/