图 1. 附一张图文不符的图

相信大家稍微看过AMXX函数的也会知道,
AMXX有三种函数可以生成随机数字:
复制程式
native random(max) //可以抽取 0 至 (max - 1) 范围内的整数
native Float:random_float(Float:a, Float:b); // 可以抽取 a 至 b 范围内的小数
native random_num(a, b) // 可以抽取 a 至 b 范围内的正负整数
乍看一下没啥分别也是产生随机数字
但其实两者在运作上不相同:
random_float 、random_num是直接向引擎获取随机数
而random()则是使用AmxModx内置生成随机数
你问我知道这些有啥用?
呃,没错的确听起来没啥用
不过既然两者实现方式不同,那执行速度上可能就有差别喔...?

以下是使用
分析器分别执行10000次测试出来:
random(20) time :
0.000093187176
0.000094055468
0.000090957132
random_num(0,20) time :
0.000162057616
0.000242643696
0.000160149244
random_float(0.0,20.0) time:
0.000151322136
0.000199439368
0.000146716752
从结果可见,同样是抽取0至20范围内的数字, random() 整体在速度上会比 random_num() 快

,
如果你喜欢运行速度快
(即使你完全体感不出来
),你可能会想选择用random()

-----------------------------------------
但random()只能抽「 0 至 max-1」的条件下,会有许多情况下也不适用,

所以在这分享一些从网上找到的公式,令 random() 整体实用性提升

:
random_chance复制程式
#define random_chance(%0) (%0 > random(100))
random_chance(25) 执行10000次的速度 :
0.000096780092
0.000096626784
0.000093949460
检查机率百分比,若抽中了会回传1,反之则回传0,
由于不需运算所以效能跟本身 random() 几乎没差别
random_fastgetnum复制程式
#define random_fastgetnum(%0,%1) (random(%1 - %0 + 1) + %0)
random_fastgetnum(0,20) 执行10000次的速度 :
0.000091732720
0.000110157688
0.000091345996
可以抽取 %0 至%1 范围内的数字,但只限正整数
random_sighnum复制程式
#define random_sighnum(%0) (random(2 * %0 + 1) - %0)
random_sighnum(20) 执行10000次的速度 :
0.000106322552
0.000105548456
0.000127152180
可以抽取 0 至 %0 范围内的数字,并会随机将数字转为正数或负数
random_getnum复制程式
#define random_getnum(%0,%1) (%0 + (random(RAND_MAX) % (%1 - %0 + 1)))
random_getnum(-20,20) 执行10000次的速度 :
0.000149931260
0.000141040200
0.000122050440
相比random_fastgetnum,这个可以抽取 %0 至%1 范围内的正负整数,
所以用途很广泛,但因要进行% 运算所以执行速度较慢 (接近random_num所需效能)
如果你是以效能优先,建议跟 random_fastgetnum、random_sighnum 灵活配合运用
random_slowgetnum复制程式
#define random_slowgetnum(%0,%1) (floatround(((float(random(RAND_MAX)) / float(RAND_MAX) * (%1 - %0 + 1)) + %0), floatround_floor))
random_slowgetnum(-20,20) 执行10000次的速度 :
0.000478622104
0.000423543492
0.000444157876
这个可以抽取 %0 至%1 范围内的正负整数,
但由于需进行不少浮点数运算,所以执行速度是所有公式之中最慢,
唯一好处是由于将要抽的数字拆分成0.0至1.0小数,然后再运算得出范围内的整数,
所以"可能"体感上抽取数字会更均匀一点,
就好像 random(2) 和 (random(50) > 25) 体感上后者数字更随机,即使机率一样,
除非有特别需求,否则整体上建议使用random_getnum就好
randomf复制程式
#define randomf(%0) (Float:((float(random(RAND_MAX)) / float(RAND_MAX)) * Float:%0))
randomf(20.0) 执行10000次的速度 :
0.000258840008
0.000240448800
0.000254451900
可以抽取 0至 %0 范围内的小数,但因为要进行浮点数除法,
所以会被原生random_float慢,
要不要使用就自己衡量,这里只提供给大家参考用
random_getfloat复制程式
#define random_getfloat(%0,%1) (Float:(float(random(RAND_MAX)) / float(RAND_MAX) * (Float:%1 - Float:%0)) + Float:%0)
random_getfloat(0.0,20.0) 执行10000次的速度 :
0.000356375972
0.000366431980
0.000398652484
可以抽取 %0至%1 范围内的小数
但缺点同上,同样只提供给大家参考用
--------------------------------------------------------
如果你看完对random()有兴趣想试试看,

你可以下载附件random.inc,
在自己源码加上#include <random>便可使用上面的define了~
