51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 6066|回复: 18
打印 上一主题 下一主题

[原创] Rand函数在执行时带来的困惑

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2007-4-30 11:01:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这段代码在Genaration中执行时,每次输出的随机数都是正常的,范围在0-100之内,但是到Controller中执行,100用户,执行1次退出,得出的结果却非常的有规律;这是为什么?

百思不得其解,特来求助~

Action()
{
long file;
int rnd;
srand(time(NULL));
rnd = rand()%100;
if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d\n", rnd);
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d\n", rnd);
    fclose(file);
}
return 0;
}


附件是某次执行完成后的结果。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
发表于 2007-4-30 11:24:31 | 只看该作者
关于随机函数,以前编程的时候接触过,这个函数如果单独使用,第一次取出的随机数基本都是固定的,而且这个固定的数和你的机器配置有关。顺着这个道理,我觉得你在Genaration中执行时,因为是连续执行,所以可以正常取随机数,但是在controller中,是同时执行,也就是说每个随机函数都是第一次调用,所以就出现随机数不随机的情况。
解决的办法,当时学c编程,是把系统时间和随机函数一起用,具体的我记不清啦,很久没用过这个函数了。大概描述一下哈,把系统时间转换成整型,乘以随机函数,这样每次调用就会不一样。
但是可能还会出现一个问题,因为是并发,就算微观不是并发,但是时间间隔仍然很短,如果用系统的秒相乘,可能大部分用户的秒还是一样的,如果能用毫秒(这个我没试过,如果不行,可以顺这个思路往下走),应该可以。

我的思路是这样的,如果有不对的,欢迎拍砖~~~~
斑竹不要说我误人子弟哈sdlkfj1
回复 支持 反对

使用道具 举报

该用户从未签到

3#
 楼主| 发表于 2007-4-30 11:55:04 | 只看该作者
楼上的解释我理解了,你说的完全正确~

刚看了Zee版的一篇文章,对Rand调用前的srand函数也明确了很多;
srand是给了rang函数一个种子,rand根据Srand提供的time进行随机取值,这一点可痛苦了。

既然是并发,那么在这个点上面的time值几乎是一致的,就算差也差不到哪儿去,所以随机值也有可能会落到某一小段范围内。

这和我最初想要的随机分配的初衷又违背了。
先去吃饭,下午来继续想问题。
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2007-5-16 17:47:21 | 只看该作者
我也正迷惑这个问题,大家继续讨论啊,不能半途而废。
回复 支持 反对

使用道具 举报

该用户从未签到

5#
发表于 2007-5-16 18:28:44 | 只看该作者
是种子的问题

如果种子是个固定的或者种子的范围比较有规律 生成的随机数也同样

把种子取成系统当前的时间或者日期或者随时都不同的数字,比如GUID


srand((unsigned)time(NULL));
程序执行的CPU时间较快,调用time函数获取的时间精度却较低(55ms),这样循环体内每次产生随机数用到的种子数都是一样的,因此产生的随机数也是一样的。


srand((unsigned)timeGetTime());//产生随机数种子
这样可以使得每次产生的随机数序列不同。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。

这些都是伪随机数!
回复 支持 反对

使用道具 举报

该用户从未签到

6#
发表于 2007-8-24 17:50:50 | 只看该作者
加入User id
lr_whoami(&id, &vuser_group, NULL);

把ID和随机数联起来就不一样了.


vuser_init()
{
int id;
char *vuser_group;
long file;
int rnd;
srand(time(NULL));
rnd = rand()%100;
lr_whoami(&id, &vuser_group, NULL);
if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
    fprintf(file,"%d\n", id);
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
        fprintf(file,"%d\n", id);
    fclose(file);
}
        return 0;
}

[ 本帖最后由 mfktafd 于 2007-8-24 17:53 编辑 ]
回复 支持 反对

使用道具 举报

该用户从未签到

7#
发表于 2007-8-24 21:44:13 | 只看该作者
sdlkfj3
回复 支持 反对

使用道具 举报

该用户从未签到

8#
发表于 2007-8-25 00:04:33 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

该用户从未签到

9#
发表于 2007-8-25 00:04:39 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

该用户从未签到

10#
发表于 2007-8-25 00:04:53 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

该用户从未签到

11#
发表于 2007-8-25 00:05:05 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

该用户从未签到

12#
发表于 2007-8-25 00:05:16 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

该用户从未签到

13#
 楼主| 发表于 2007-8-25 00:19:20 | 只看该作者
汗,楼上这谁灌水啊~
谢谢mfktafd ,
但是,
我假如想生成在0到100范围内的随机数呢?
回复 支持 反对

使用道具 举报

该用户从未签到

14#
发表于 2007-8-25 01:09:37 | 只看该作者
原帖由 Athenst 于 2007-8-25 00:19 发表
汗,楼上这谁灌水啊~
谢谢mfktafd ,
但是,
我假如想生成在0到100范围内的随机数呢?


晕,楼主还是没看懂啊,srand只是用某个值初始化种子,不影响rand的取值范围的。
回复 支持 反对

使用道具 举报

该用户从未签到

15#
 楼主| 发表于 2007-8-25 13:28:33 | 只看该作者
原帖由 yabest 于 2007-8-25 01:09 发表


晕,楼主还是没看懂啊,srand只是用某个值初始化种子,不影响rand的取值范围的。


是的,我是还没懂~
要不你做一个结果来看看?

100个用户并发,每个用户生成一个0-100之间的随机数,写到一个txt文件里面去。

把脚本贴上来就可以了。
回复 支持 反对

使用道具 举报

该用户从未签到

16#
发表于 2007-8-25 16:50:58 | 只看该作者
typedef long Clock_t;

Action()
{

//Clock_t time1;
long file;
int rnd;

   int id;
    char *vuser_group;
    double sin(double x) ;
float t,t1;
lr_whoami(&id, &vuser_group, NULL);
t=sin(id)*100000;

//取一个Id的Sin位置
t1=sin(clock())*100000;

//取一个开始计时的Sin位置
//time1=clock();

lr_rendezvous("111");

//lr_rendezvous(111);
srand(t+t1);

//这样Srand得到的值应该是比较随机的数值位置了.
//srand(time(NULL));
rnd = rand()%100;
//lr_output_message("%lf",sin(id));
if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
fprintf(file,"%lf : ",t+t1);
    fprintf(file,"%d\n", rnd);
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
fprintf(file,"%lf : ",t+t1);
    fprintf(file,"%d\n", rnd);
    fclose(file);
}

return 0;
}
这个是我目前想到的最随机的方法了...


[ 本帖最后由 mfktafd 于 2007-8-28 10:51 编辑 ]
回复 支持 反对

使用道具 举报

该用户从未签到

17#
 楼主| 发表于 2007-8-25 17:08:34 | 只看该作者
嗯,谢谢mfktafd ~其实我想知道的就是种子的随机。

你现在的做法中,种子并不是随机的,所以导致了rand结果并不是0-100随机,假如打成图的话相信一定有某种规律曲线吧。

嗯,不过还是很佩服你的热心!

这帖子就不要跟了,请沉底。

[ 本帖最后由 Athenst 于 2007-8-25 17:17 编辑 ]
回复 支持 反对

使用道具 举报

该用户从未签到

18#
发表于 2007-8-26 08:01:29 | 只看该作者
sdlkfj3
回复 支持 反对

使用道具 举报

该用户从未签到

19#
发表于 2007-8-28 15:03:20 | 只看该作者
呵呵,我是用LR的随机参数来实现的,在controller中可以并发100用户可以生成0-100的随机数,不知道是否满足你的要求。

Action()
{
char* str;
long file;
int rnd;
srand(time(NULL));
rnd = rand()%100;
//abc是一个random类型的参数
lr_save_string(lr_eval_string("{abc}"),"str");


if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
        fprintf(file,"                %s\n",lr_eval_string("{str}"));
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
        fprintf(file,"                %s\n",lr_eval_string("{str}"));
    fclose(file);
}
return 0;
}

[ 本帖最后由 ppent 于 2007-8-28 15:06 编辑 ]
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-26 06:56 , Processed in 0.070656 second(s), 27 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表