Xcode 中 rand() 的奇怪行为 [英] Strange behaviour of rand() in Xcode

查看:57
本文介绍了Xcode 中 rand() 的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 Apple Xcode 时,我在下面包含的 C 程序将始终为 y 返回 5,但 z 将返回一个随机数,即使它们具有相同的表达式.你能找出这种行为的原因吗?

While using Apple Xcode, the C program I include below will always return a 5 for y but z will return a random number, even though they have the same expression. Can you identify a reason for this behaviour?

#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

这是您的程序的改编版,它显示了正在发生的事情的更多细节:

Here's an adaptation of your program which shows more detail of what's going on:

#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() 的值与打印的值相同,尽管它们不同的可能性很小.

It captures the result of the two rand() calls independently of the calculation so that they can be printed. It also ensures that the value passed to time() is the same as the value printed, though the chances of them being different are pretty small.

当我运行几次时,我得到了输出:

When I ran it a few times, I got the outputs:

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() 返回的值不同,但差别不大,因此计算出的值也没有太大不同.

As you can see, the values returned by rand() are different, but not very different, and consequently the computed value isn't all that different.

rand-23

一个简单的升级选项是使用 drand48() 函数,像这样:

One easy upgrade option is to use the drand48() functions, like this:

#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范围内的值..231-1.

The code prints RAND_MAX mainly to show that it is compatible with the range of values returned by lrand48(), which is documented to return a value in the range 0..231-1.

这给出了不同的并且可以说是更好的结果:

This gives different and arguably better results:

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 文档,但功能最近没有改变.

Alternatively, you can do what the macOS documentation says and switch to arc4random(). The link is to 'legacy' XCode 5 documentation, but the functionality hasn't changed recently.

#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() 函数系列的类似物.

This uses arc4random_uniform() to generate a value in the range 0..INT_MAX, the same range as the other functions generated. There is no analogue to srand() with the arc4random() family of functions.

样品运行:

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) 而不是做计算.

Note that if you want a random integer between 0 and 10, then you should use arc4random_uniform(10) directly and not do the computations.

#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() 等的另一个优点.对于其他生成器,由于使用相同的种子,这些生成器会产生相同的结果.

One further advantage of arc4random() et al is shown when I managed to run the program 3 times in a single second. With the other generators, these would have produced the same results because of using the same seed.

$ 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)进行编译,但是系统库——这里是关键的库.

JFTR: Code compiled on a MacBook Pro running macOS High Sierra 10.13. I used GCC 7.2.0 (rather than XCode 9) to compile, but the system library — and it is the library that is critical here.

这篇关于Xcode 中 rand() 的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆