50 lines
956 B
Go
50 lines
956 B
Go
package mt19937
|
|
|
|
import (
|
|
"log"
|
|
)
|
|
|
|
type UniformIntDistribution struct {
|
|
m_min int64
|
|
m_max int64
|
|
m_eng *MT19937
|
|
}
|
|
|
|
func DistInt64(eng *MT19937, begin int64, end int64) *UniformIntDistribution {
|
|
if begin > end {
|
|
log.Println("ERROR! begin is not allowed to be greater than end!")
|
|
return nil
|
|
}
|
|
|
|
dist := &UniformIntDistribution{
|
|
m_min: begin,
|
|
m_max: end,
|
|
m_eng: eng,
|
|
}
|
|
return dist
|
|
}
|
|
|
|
func (dist *UniformIntDistribution) Int64() int64 {
|
|
var rng uint64
|
|
|
|
if dist.m_min >= 0 {
|
|
rng = uint64(dist.m_max) - uint64(dist.m_min)
|
|
} else if dist.m_max >= 0 {
|
|
rng = uint64(dist.m_max) + uint64(-(dist.m_min + 1)) + 1
|
|
} else {
|
|
rng = uint64(dist.m_max - dist.m_min)
|
|
}
|
|
|
|
if rng == 0 {
|
|
return dist.m_min
|
|
} else if rng == ^uint64(0) {
|
|
return int64(dist.m_eng.Random())
|
|
}
|
|
bucket_size := ^uint64(0) / (rng + 1)
|
|
if ^uint64(0)%(rng+1) == rng {
|
|
bucket_size++
|
|
}
|
|
result := dist.m_eng.Random() / bucket_size
|
|
return int64(result) + dist.m_min
|
|
}
|