Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

随机数生成算法错误, 导致生成的随机数并非均匀分布 #7

Open
Xiangze-Li opened this issue Sep 6, 2024 · 1 comment

Comments

@Xiangze-Li
Copy link
Member

dicescript/roll_func.go

Lines 23 to 41 in 28fab8c

func Roll(src *rand.PCGSource, dicePoints IntType, mod int) IntType {
if dicePoints == 0 {
return 0
}
if mod == -1 {
return 1
}
if mod == 1 {
return dicePoints
}
if src == nil {
src = randSource
}
// js端有bug,如果当前IntType为32位,Int63会得到负数
// val := IntType(rand.Int31())%dicePoints + 1
// 同样问题也存在于这里,所以需要 &math.MaxInt32
val := IntType(src.Uint64()&math.MaxInt32)%dicePoints + 1
return val
}

在 39 行对生成的随机数直接使用了取模运算. 由于生成的随机数是在非负 int32 上均匀的, 当 dicePoints 不是 2 的幂时, 导致较小余数出现的概率将比较大余数大.

如何验证问题存在: 统计 d1431000000 的分布. 由于这个数足够大, 可以使小出目的概率达到大出目的 2 倍.

@fy0
Copy link
Member

fy0 commented Sep 7, 2024

大概是修复了,经过了不严谨的测试:
20000d1431000000 = 14336068183245
20000d1431000000 = 14348112861946
20000d1431000000 = 14250829103396

(1431000000 / 2 + 1) *20000
____________________ = 14310000020000

https://github.com/sealdice/dicescript/blob/main/roll_func.go#L44-L62

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants