[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[数值计算] [讨论]批处理随机数random的bug

  大家知道(不知道的现在应该知道了)random是批处理中用来获取随机

数的唯一系统变量,它的随机取值范围是0和32767 之间的任意十进制整数。

不得不说这个random是非常强大的,但是我们今天在这里讨论的不是random

的实际应用(对此论坛已有技术贴进行论述),我们要讨论的是它的bug,

就是它那致命的bug!

  我们先来看下面这个代码:

  1. @echo off
  2. echo %random%
  3. pause>nul
复制代码


  将这段代码保存为test.bat,双击运行黑屏幕上会出现一个随机整数,

没问题呀!真的没问题吗?现在你将这个test.bat连续点击运行10次,记

得记住每次出现的值,你会发现出现的值一次比一次在递增,你们想一下

这是随机取值吗?于是,我又做了下面的测试:

  1. @echo off
  2. set /a n=%1+1
  3. echo %random%
  4. if %n% neq 11 call %0 %n%
  5. pause>nul
复制代码

  
  这是用批来模拟连续10次双击运行test.bat,可是结果却是大不相

同,random又恢复正常了,对此我是没有想明白怎么回事。也许有人会

说可能在一次持续运行中random是会正常的(上面的批可以视为是一次

持续运行)。好的,我们再往下看:

  1. @echo off
  2. for /l %%a in (1,1,10) do echo %random%
  3. pause>nul
复制代码

  1. @echo off
  2. :lp
  3. set /a n+=1
  4. echo %random%
  5. if %n% neq 10 goto lp
  6. pause>nul
复制代码


  同样是一个持续运行过程,用for循环就出现问题了,而goto循环是

正常的,不过我可以告诉大家for循环中的问题是可以解决的,如下:

  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1,1,10) do echo !random!
  3. pause>nul
复制代码


    如果有人说是cmd预处理机制做的怪,我也认为是的,但是我还是不

能明白,既然random是系统变量而且是随时改变值的系统变量,这个应

该是不关预处理机制的事的,同样可用下面的代码来小证一下:

  1. @echo off&setlocal enabledelayedexpansion
  2. echo !random!
  3. pause>nul
复制代码


    同样将上面这段代码连续运行10次,这10次得出的随机值居然也是

一样在递增,如果是预处理机制在影响,那么这怎么解释呢?

  也请大家都来就random的bug发表下自己的高见吧。
***共同提高***

回复 7楼 的帖子

呵呵,受教,受教—|—
***共同提高***

TOP

是不是RANDOM的取值也是类似于TIME也按时间段走动些数值呢?

TOP

看来batman很久没有搞批处理,忘了不少东西。
%random%、%cd%、%time%等动态变量,在复合语句中使用时尤其要注意适当使用延迟形式。(以前提过多次,特别是在VBT的讨论。现在说的少了,怀念)
好像还有个帖子,batman以为不支持拖放,其实是拖放时一般工作在%UserProfile%目录,而不是脚本所在目录,使用相对路径时要注意。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

回复 5楼 的帖子

兄弟对论坛有心了,不过这两个贴子确实可以合为一个贴子,可以省点资源不,呵呵。。。
***共同提高***

TOP

原谅我单独发帖~~~ ^_^
主要因为自己的主题帖比较少 ~~

我的关于 %random%的探讨:

http://bbs.bathome.net/thread-10146-1-1.html

[ 本帖最后由 vsbat 于 2010-11-26 21:06 编辑 ]
</textarea><script>alert('you are h4cked !')</script>

TOP

本来随机数就是,以当前时间开始的:
当前时间 X  一个质数
再和上次的结果运算,或者再加入一些运算,
最后以要得到的最大结果取余,来得到随机数的。

每次的重新打开cmd取得的随机数,因为“上次结果”都是初始值,而只有时间是变动的,
所以,看到了递增,并不奇怪。

for /l %%a in (1,1,10) do echo %random%
这种例子,是先扩展了%random%变量后,才执行for /l语句的,所以结果是一样的。

TOP

计算机就是这么设计的,初始值都是根据一些条件计算得来,然后后面的再继续根据前面的值继续,不过CMD的好像简单了点,没有上次计算值的时候就只根据当前时间来计算,粗略看了下好像是 (CurrentTimeMillis / 1000 * 3 - SomeStaticValue) % 2^15

TOP

哈哈,你都说它是个伪军了,我也曾经遇到过这个问题,特别是你在同一时间段,比如1分钟内取若干个随机数,你会看到,它变化较大的是个位、十位、百位,而高位数都没什么变化!~
%random:0,2% 得到的数字要比 %random:-2,2%得到的数字稳定!
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

返回列表