有关 Go 语言中 Rand 函数的一行代码

2021-06-16 10:07:19 +08:00
 mangoDB

https://github.com/golang/go/blob/abc56fd1a0505d4fc27943cbcda81ac783fb2d2f/src/math/rand/rand.go#L135

请问上述代码中第 135 行是什么含义?

我理解这行代码的目的应该是想得到一个可以被 n 整除的最大值,使得最终生成的随机数是等概率的。

那么我是否可以将这行代码由:

max := int32((1 << 31) - 1 - (1<<31)%uint32(n))

替换为:

max := int32((1 << 31) - 1 - ((1 << 31) - 1)%uint32(n) - 1)

请万能的 V 友指点。

1390 次点击
所在节点    问与答
7 条回复
AoEiuV020
2021-06-16 10:32:28 +08:00
不明觉历,这前后不等价吧,把 n=(1<<31)代入算一下?
AoEiuV020
2021-06-16 10:44:45 +08:00
go lang 整数溢出居然不能强制转换的吗? 1<<31 居然无法转成 int32, 这里写了个-1<<31 代入的代码,
mainjzb
2021-06-16 11:22:00 +08:00
你的理解是对的,你的替换代码是错的
代入 n=100, 得 max=2147483599
mainjzb
2021-06-16 11:22:36 +08:00
你的理解是对的,你的替换代码是错的
代入 n=100, 得 max=2147483599
max 的值是[0,2147483599] 正好是 2147483600 个数字
mainjzb
2021-06-16 11:28:21 +08:00
前面-1 是因为他要算入 0 这个数字,后面正常思考就行

int32((1 << 31) - 1) = [0, 2147483647]
max = [0, 2147483647 - (2147483648%n)]
lujjjh
2021-06-16 11:59:42 +08:00
> 我理解这行代码的目的应该是想得到一个可以被 n 整除的最大值

其实是得到一个最大的 max 使得 n | (max + 1),因为这里 max 是可以取到的。

也可以改成

max := (1<<31) - (1<<31)%uint32(n)
...
for uint32(v) >= max {
mangoDB
2021-06-16 13:24:25 +08:00
@AoEiuV020
@mainjzb
@lujjjh

感谢各位回复,我最初将 `(1 << 31) - 1` 统一替换成了 `MAX_INT32` 去理解,走了歪路。看见大家的讲解之后,思路变得清晰,谢谢大家。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/783657

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX