V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
mangoDB
V2EX  ›  问与答

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

  •  
  •   mangoDB · 167 天前 · 795 次点击
    这是一个创建于 167 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 友指点。

    7 条回复    2021-06-16 13:24:25 +08:00
    AoEiuV020
        1
    AoEiuV020   167 天前
    不明觉历,这前后不等价吧,把 n=(1<<31)代入算一下?
    AoEiuV020
        2
    AoEiuV020   167 天前
    go lang 整数溢出居然不能强制转换的吗? 1<<31 居然无法转成 int32, 这里写了个-1<<31 代入的代码,
    mainjzb
        3
    mainjzb   167 天前
    你的理解是对的,你的替换代码是错的
    代入 n=100, 得 max=2147483599
    mainjzb
        4
    mainjzb   167 天前
    你的理解是对的,你的替换代码是错的
    代入 n=100, 得 max=2147483599
    max 的值是[0,2147483599] 正好是 2147483600 个数字
    mainjzb
        5
    mainjzb   167 天前
    前面-1 是因为他要算入 0 这个数字,后面正常思考就行

    int32((1 << 31) - 1) = [0, 2147483647]
    max = [0, 2147483647 - (2147483648%n)]
    lujjjh
        6
    lujjjh   167 天前
    > 我理解这行代码的目的应该是想得到一个可以被 n 整除的最大值

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

    也可以改成

    max := (1<<31) - (1<<31)%uint32(n)
    ...
    for uint32(v) >= max {
    mangoDB
        7
    mangoDB   167 天前
    @AoEiuV020
    @mainjzb
    @lujjjh

    感谢各位回复,我最初将 `(1 << 31) - 1` 统一替换成了 `MAX_INT32` 去理解,走了歪路。看见大家的讲解之后,思路变得清晰,谢谢大家。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3819 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 08:37 · PVG 16:37 · LAX 00:37 · JFK 03:37
    ♥ Do have faith in what you're doing.