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 // lost by setting the high bit. return (rand.Uint64() | 0x8000000000000000) >> rand.Intn(65) } // Like RandBiasedUint64() but always returns < n func RandBiasedUint64n(n uint64) uint64 { for { ret := RandBiasedUint64() if ret < n { return ret } } } // Generate a random int64 with an even distribution of the tuple // {sign, bits.Len64(math.Abs())} func RandBiasedInt64() uint64 { shift := rand.Intn(127) // [0,62]: positive // [63,63]: zero // [64,126]: negative if shift < 64 { return uint64(int64((rand.Uint64() | 0x8000000000000000) >> (shift + 1))) } else { return uint64(int64((rand.Uint64()|0x8000000000000000)>>(shift-63)) * -1) } } // 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() } }