序列的随机数与取模
2025年4月10日
感谢我的好朋友 yw 的帮助,下面是正文
任何整数对 n 取模,结果都一定在 [0, n-1] 区间内,这是取模的本质。
对 n 取模( a % n = c) c 一定小于 n
然后我们知道随机数函数的范围往往是 0 ~ RAND_MAX = 32767
利用取模可以限定到 rand() % n
即 0 ~ n - 1
此时再补上1,即是 0 ~ n,很接近我们的目标的,但这仅仅局限于 0 开始的序列
那如果是 12 ~ 31 的序列呢?
我们可以先变成 0 ~ (31 - 12) 的序列,可以得出是 rand() % 31 - 12 + 1
这样就是 0 ~ 19
算出这样的范围后,再加上 12,即 0 + 12 ~ 19 + 12
就是 12 ~ 31
chatGPT 优化: 把目标范围 [12, 31] 先“归一化”为从 0 开始,即 [0, 31 - 12] = [0, 19]
然后用 rand() % 20 得到 [0, 19],再加回偏移量 12,最终得到 [12, 31]
总结下,我们做了哪些事?
- 我们先根据取模性质还原成从 0 开始的序列
- 为了保证在 [a, b] 之间,我们不得不先处理 [0, b - a + 1] 之间,得到这个区间后
- 再将 [0, b - a + 1] + a,即是 [a, b] 区间
2025年4月11日更新
式子优先级有误
如果按照上面的式子,得出来的并不是 [a, b],而是 [1, b]
因为
(rand() % b - a + 1) + a
=((rand() % b) - a + 1) + a
= (rand() % b) - a + 1 + a
= (rand() % b) + 1
正确是应该是
rand() % (b - a + 1) + a
chatGPT:
你的错误在于:
-
没有给取模加括号
-
数学表达式被错误地拆分了,导致实际范围被改变
-
没有用 (b - a + 1) 控制随机范围的“长度”
-
最后加的 a 没有真正作为“起始值”加进去

浙公网安备 33010602011771号