Skip to content

Commit

Permalink
refactor: 改进取随机数的写法
Browse files Browse the repository at this point in the history
  • Loading branch information
fy0 committed Sep 7, 2024
1 parent 1135c3e commit b06b5f3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 23 deletions.
64 changes: 43 additions & 21 deletions roll_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,67 @@ func getSource() *rand.PCGSource {

var randSource = getSource()

func Roll(src *rand.PCGSource, dicePoints IntType, mod int) IntType {
if dicePoints == 0 {
return 0
}
// 这里判断不了IntType的长度,但编译器会自动优化掉没用的分支
// 注: 由于 gopherJs 会因为 MaxInt64 > uint_max 而编译错误,所以限制最大值为int32,看他后续版本是否会有改进
// if IntTypeSize == 8 && dicePoints > math.MaxInt64-1 {
// return 0
// }
// if IntTypeSize == 4 && dicePoints > math.MaxInt32-1 {
// return 0
// }
func _roll32(src *rand.PCGSource, dicePoints int) int {
// 注: int的长度至少为32位,也可以高于此数,此处只是当作32位处理
if dicePoints > math.MaxInt32-1 {
return 0
}

if mod == -1 {
return 1
v := uint32(src.Uint64() >> 32)
n := uint32(dicePoints)
// 下面这段取整代码来自 golang 的 exp/rand
if n&(n-1) == 0 { // n is power of two, can mask
return int(v&(n-1) + 1)
}
if mod == 1 {
return dicePoints
if v > math.MaxUint32-n { // Fast check.
ceiling := math.MaxUint32 - math.MaxUint32%n
for v >= ceiling {
v = uint32(src.Uint64() >> 32)
}
}
if src == nil {
src = randSource
return int(v%n + 1)
}

func _roll64(src *rand.PCGSource, dicePoints int64, mod int) int64 {
if dicePoints > math.MaxInt64-1 {
return 0
}

v := src.Uint64() // 如果弄32位版本,可以写成 uint32(src.Uint64() >> 32)
v := src.Uint64()
n := uint64(dicePoints)
// 下面这段取整代码来自 golang 的 exp/rand
if n&(n-1) == 0 { // n is power of two, can mask
return IntType(v&(n-1) + 1)
return int64(v&(n-1) + 1)
}
if v > math.MaxUint64-n { // Fast check.
ceiling := math.MaxUint64 - math.MaxUint64%n
for v >= ceiling {
v = src.Uint64()
}
}
return IntType(v%n + 1)
return int64(v%n + 1)
}

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
}

// 大部分情况会走这个分支
if IntTypeSize == 8 {
return IntType(_roll64(src, int64(dicePoints), mod))
}

return IntType(_roll32(src, int(dicePoints)))
}

func wodCheck(e *Context, addLine IntType, pool IntType, points IntType, threshold IntType) bool {
Expand Down
4 changes: 2 additions & 2 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import (
)

type VMValueType int
type IntType int // :IntType
const IntTypeSize = 4 // 只能为 4 或 8(32位/64位)
type IntType int // :IntType
const IntTypeSize = strconv.IntSize / 8 // 只能为 4 或 8(32位/64位)

const (
VMTypeInt VMValueType = 0
Expand Down

0 comments on commit b06b5f3

Please sign in to comment.