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

[数值计算] 批处理生成指定范围内的随机数

  1. :rndnum
  2. set lnum=%~1
  3. set unum=%~2
  4. if "%lnum%" == "" (set lnum=1)
  5. if "%unum%" == "" (set unum=9)
  6. if %lnum% GTR %unum% (set lnum=%unum%&set unum=%lnum%)
  7. set /a rnd=(%unum% - %lnum% + 1) * %random% / 32768 + %lnum%
  8. goto :eof
复制代码
其中%random%的范围为0-32767,那么这个随机小数就可以通过除以32768获得,剩下的取整不需要人工干预,批处理就自动解决了。

生成随机数的范围:大于等于最小值,小于等于最大值

为了确定是否稳定,测试了10W次
测试代码如下:
  1. @echo off
  2. setlocal ENABLEDELAYEDEXPANSION
  3. :s
  4. cls
  5. for /l %%a in (1,1,100000) do (
  6. call :rndnum
  7. echo. %%a 中间结果:!rnd!
  8. if 1!rnd! GTR 19 (call :over !rnd!)
  9. if 1!rnd! LSS 11 (call :over !rnd!)
  10. )
  11. echo.
  12. echo.
  13. echo.计算结束!
  14. echo.
  15. echo.
  16. pause
  17. exit
  18. :rndnum
  19. set lnum=%~1
  20. set unum=%~2
  21. if "%lnum%" == "" (set lnum=1)
  22. if "%unum%" == "" (set unum=9)
  23. if %lnum% GTR %unum% (set lnum=%unum%&set unum=%lnum%)
  24. set /a rnd=(%unum% - %lnum% + 1) * %random% / 32768 + %lnum%
  25. goto :eof
  26. :over
  27. cls
  28. echo.
  29. echo.
  30. echo. 调试结果:%~1
  31. echo.
  32. echo.
  33. pause
  34. goto :eof
复制代码
1

评分人数

当一个人不断追问的时候,其实就已经对自己产生了怀疑

其实关键的就这一句,常做软件开发的应该都知道,这个是生成指定范围内随机数的公式
只不过那个0-1之间的随机小数通过%random%/32768生成。

  1. set /a rnd=(%unum% - %lnum% + 1) * %random% / 32768 + %lnum%
复制代码


这个做成函数了,使用 call :rndnum 最小值 最大  调用,若不传参数,默认生成1-9之间的随机数
当一个人不断追问的时候,其实就已经对自己产生了怀疑

TOP

回复 5楼 的帖子

在P中,计算顺序是先算括号,然后按照优先级从左往右计算

这样,上面的
  1. set /a rnd=(%unum% - %lnum% + 1) * %random% / 32768 + %lnum%
复制代码
1。算括号里面的加减
2。然后是乘以随机数
3。再计算除法,这样生成的就是个整数,范围在最大数和0之间

4。此时加上最小数,范围就被定下来了。

这个算法变相取得了随机小数,呵呵。
另外,这个32768个人感觉有点不对劲,貌似应该是32767,这样结果才不会偏小。
看了看随机数的范围,越看越觉得应该是32767。大家再研究吧,呵呵

[ 本帖最后由 qq362220083 于 2009-3-31 14:51 编辑 ]
当一个人不断追问的时候,其实就已经对自己产生了怀疑

TOP

头大!!!
  1. set /a rnd=(%unum% - %lnum% + 1) * %random% / 32768 + %lnum%
复制代码
中,按照咱们平时的随机数,应该是像下面这样
  1. set /a rnd=(%unum% - %lnum% + 1) * (%random% / 32768) + %lnum%
复制代码
但由于乘法和除法处于同一优先级,因此,先计算除法和先计算乘法的结果一样。这个是理论上的。
但是,在批处理中,无法计算小数,批处理会把结果中的小数直接舍掉。若按照正常的计算顺序,会造成结果永远都是最小值,因为
  1. %random% / 32768
复制代码
永远是0-1之间的小数,批处理总是舍掉小数变成0,任何数乘以0结果不用我重复吧

因此我就按照数学上的四则运算法则,把计算顺序变为先计算乘法,后计算除法,这样的结果同样会被批处理省略掉小数,但这却正好帮了忙,省去了最后取整的过程。

还有,这个随机结果会比正常结果偏小0.5左右,理论上的。我想大家不需要那么精确吧,呵呵

另外,Batcher,你要是还不明白,我就无能为力了,真的怀疑你的小学数学老师。。。

[ 本帖最后由 qq362220083 于 2009-4-10 05:19 编辑 ]
当一个人不断追问的时候,其实就已经对自己产生了怀疑

TOP

好久没来了,今天来转转,看到这个帖子。呵呵,心里有点感触了。。。


使用%random%取得的随机数范围在0 和 32767之间

%random% / 32767  就是范围在0-1之间的小数

但是批处理中,对于数学运算,若结果是小数,则自动忽略小数,只取结果中的整数部分

因此%random% / 32768在批处理中只会得到0

但四则运算法则中,乘法和除法是同一优先级,同样批处理也遵守。所以,可以乘以一个随机整数,然后除以随机整数的最大值,得到一个随机范围在0与(最大值-最小值)之间的整数。最后加上最小值!

例子:

得到1-10之间的随机数
1:10 - 1 + 1 =10
2:10 * %random%    返回的是0~327670之间的整数
3:(0~327670)/32768    返回的是0~9之间的整数,算术的最小值最大值的获取方法分别是用范围的最小值和最大值除以32768,得到的分别是算术的最小值和最大值
4:加上最小值1,返回的是1~10

[ 本帖最后由 qq362220083 于 2010-3-16 17:25 编辑 ]
当一个人不断追问的时候,其实就已经对自己产生了怀疑

TOP

返回列表