2021-11-20 15:20:42 -10:00
|
|
|
package gen
|
|
|
|
|
|
|
|
|
|
import "math/rand"
|
|
|
|
|
|
|
|
|
|
// Generate a random uint64 with an even distribution of bits.Len64()
|
|
|
|
|
func RandBiasedUint64() uint64 {
|
|
|
|
|
// The shift-right by up to 64 (shifting it to 0) makes up for randomness
|
2021-11-20 18:27:06 -10:00
|
|
|
// lost by setting the high bit.
|
2021-11-20 16:56:07 -10:00
|
|
|
return (rand.Uint64() | 0x8000000000000000) >> rand.Intn(65)
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-20 18:12:17 -10:00
|
|
|
// Like RandBiasedUint64() but always returns < n
|
|
|
|
|
func RandBiasedUint64n(n uint64) uint64 {
|
|
|
|
|
for {
|
|
|
|
|
ret := RandBiasedUint64()
|
|
|
|
|
if ret < n {
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-20 16:56:07 -10:00
|
|
|
// Generate a random int64 with an even distribution of the tuple
|
|
|
|
|
// {sign, bits.Len64(math.Abs())}
|
2021-11-20 17:59:22 -10:00
|
|
|
func RandBiasedInt64() uint64 {
|
2021-11-20 16:56:07 -10:00
|
|
|
shift := rand.Intn(127)
|
|
|
|
|
// [0,62]: positive
|
|
|
|
|
// [63,63]: zero
|
|
|
|
|
// [64,126]: negative
|
|
|
|
|
if shift < 64 {
|
2021-11-20 17:59:22 -10:00
|
|
|
return uint64(int64((rand.Uint64() | 0x8000000000000000) >> (shift + 1)))
|
2021-11-20 16:56:07 -10:00
|
|
|
} else {
|
2021-11-20 18:27:06 -10:00
|
|
|
return uint64(int64((rand.Uint64()|0x8000000000000000)>>(shift-63)) * -1)
|
2021-11-20 17:59:22 -10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mixture of RandBiasedUint64() and RandBiasedInt64(), with probability shifted
|
|
|
|
|
// toward more unsigned values.
|
|
|
|
|
func RandBiasedUSint64() uint64 {
|
|
|
|
|
if rand.Intn(2) == 0 {
|
|
|
|
|
return RandBiasedUint64()
|
|
|
|
|
} else {
|
|
|
|
|
return RandBiasedInt64()
|
2021-11-20 16:56:07 -10:00
|
|
|
}
|
2021-11-20 15:20:42 -10:00
|
|
|
}
|