标题: [数值计算] [讨论]批处理随机数random的bug [打印本页]
作者: batman 时间: 2010-11-26 15:49 标题: [讨论]批处理随机数random的bug
大家知道(不知道的现在应该知道了)random是批处理中用来获取随机
数的唯一系统变量,它的随机取值范围是0和32767 之间的任意十进制整数。
不得不说这个random是非常强大的,但是我们今天在这里讨论的不是random
的实际应用(对此论坛已有技术贴进行论述),我们要讨论的是它的bug,
就是它那致命的bug!
我们先来看下面这个代码:
- @echo off
- echo %random%
- pause>nul
复制代码
将这段代码保存为test.bat,双击运行黑屏幕上会出现一个随机整数,
没问题呀!真的没问题吗?现在你将这个test.bat连续点击运行10次,记
得记住每次出现的值,你会发现出现的值一次比一次在递增,你们想一下
这是随机取值吗?于是,我又做了下面的测试:
- @echo off
- set /a n=%1+1
- echo %random%
- if %n% neq 11 call %0 %n%
- pause>nul
复制代码
这是用批来模拟连续10次双击运行test.bat,可是结果却是大不相
同,random又恢复正常了,对此我是没有想明白怎么回事。也许有人会
说可能在一次持续运行中random是会正常的(上面的批可以视为是一次
持续运行)。好的,我们再往下看:
- @echo off
- for /l %%a in (1,1,10) do echo %random%
- pause>nul
复制代码
- @echo off
- :lp
- set /a n+=1
- echo %random%
- if %n% neq 10 goto lp
- pause>nul
复制代码
同样是一个持续运行过程,用for循环就出现问题了,而goto循环是
正常的,不过我可以告诉大家for循环中的问题是可以解决的,如下:
- @echo off&setlocal enabledelayedexpansion
- for /l %%a in (1,1,10) do echo !random!
- pause>nul
复制代码
如果有人说是cmd预处理机制做的怪,我也认为是的,但是我还是不
能明白,既然random是系统变量而且是随时改变值的系统变量,这个应
该是不关预处理机制的事的,同样可用下面的代码来小证一下:
- @echo off&setlocal enabledelayedexpansion
- echo !random!
- pause>nul
复制代码
同样将上面这段代码连续运行10次,这10次得出的随机值居然也是
一样在递增,如果是预处理机制在影响,那么这怎么解释呢?
也请大家都来就random的bug发表下自己的高见吧。
作者: cjiabing 时间: 2010-11-26 17:24
哈哈,你都说它是个伪军了,我也曾经遇到过这个问题,特别是你在同一时间段,比如1分钟内取若干个随机数,你会看到,它变化较大的是个位、十位、百位,而高位数都没什么变化!~
%random:0,2% 得到的数字要比 %random:-2,2%得到的数字稳定!
作者: zz100001 时间: 2010-11-26 18:20
计算机就是这么设计的,初始值都是根据一些条件计算得来,然后后面的再继续根据前面的值继续,不过CMD的好像简单了点,没有上次计算值的时候就只根据当前时间来计算,粗略看了下好像是 (CurrentTimeMillis / 1000 * 3 - SomeStaticValue) % 2^15
作者: netbenton 时间: 2010-11-26 19:44
本来随机数就是,以当前时间开始的:
当前时间 X 一个质数
再和上次的结果运算,或者再加入一些运算,
最后以要得到的最大结果取余,来得到随机数的。
每次的重新打开cmd取得的随机数,因为“上次结果”都是初始值,而只有时间是变动的,
所以,看到了递增,并不奇怪。
for /l %%a in (1,1,10) do echo %random%
这种例子,是先扩展了%random%变量后,才执行for /l语句的,所以结果是一样的。
作者: vsbat 时间: 2010-11-26 21:04
原谅我单独发帖~~~ ^_^
主要因为自己的主题帖比较少 ~~
我的关于 %random%的探讨:
http://bbs.bathome.net/thread-10146-1-1.html
[ 本帖最后由 vsbat 于 2010-11-26 21:06 编辑 ]
作者: batman 时间: 2010-11-26 21:08 标题: 回复 5楼 的帖子
兄弟对论坛有心了,不过这两个贴子确实可以合为一个贴子,可以省点资源不,呵呵。。。
作者: zqz0012005 时间: 2010-11-26 21:59
看来batman很久没有搞批处理,忘了不少东西。
%random%、%cd%、%time%等动态变量,在复合语句中使用时尤其要注意适当使用延迟形式。(以前提过多次,特别是在VBT的讨论。现在说的少了,怀念)
好像还有个帖子,batman以为不支持拖放,其实是拖放时一般工作在%UserProfile%目录,而不是脚本所在目录,使用相对路径时要注意。
作者: wc726842270 时间: 2010-11-26 22:12
是不是RANDOM的取值也是类似于TIME也按时间段走动些数值呢?
作者: batman 时间: 2010-11-26 23:20 标题: 回复 7楼 的帖子
呵呵,受教,受教—|—
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |