-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnumber.go
More file actions
90 lines (78 loc) · 2.33 KB
/
number.go
File metadata and controls
90 lines (78 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package randomizer
type Integers interface {
SignedIntegers | UnsignedIntegers
}
type SignedIntegers interface {
~int8 | ~int16 | ~int | ~int32 | ~int64
}
type UnsignedIntegers interface {
~uint8 | ~uint16 | ~uint | ~uint32 | ~uint64 | ~uintptr
}
// uniformUint64n returns a uniform value in [0, n).
func uniformUint64n(n uint64, rng *wordRNG) uint64 {
if n == 0 {
return 0
}
// threshold = 2^64 mod n
threshold := (uint64(0) - n) % n
for {
x := rng.next64()
if x >= threshold {
return x % n
}
}
}
// Int generates a random signed integer of type T.
func Int[T SignedIntegers]() T {
return T(DefaultHashPool.Sum64())
}
// IntInterval generates a random signed integer of type T within a specified range.
func IntInterval[T SignedIntegers](min, max T) T {
if min == max {
return min
}
if min > max {
min, max = max, min
}
rng := newWordRNG()
// Map signed values to a monotonic unsigned domain.
const signMask = uint64(1) << 63
minU := uint64(int64(min)) ^ signMask
maxU := uint64(int64(max)) ^ signMask
span := maxU - minU
v := uniformUint64n(span, &rng)
return T(int64((minU + v) ^ signMask))
}
// Uint generates a random unsigned integer of type T.
func Uint[T UnsignedIntegers]() T {
return T(DefaultHashPool.Sum64())
}
// UintInterval generates a random unsigned integer of type T within a specified range.
func UintInterval[T UnsignedIntegers](min, max T) T {
if min == max {
return min
}
if min > max {
min, max = max, min
}
rng := newWordRNG()
span := uint64(max - min)
v := uniformUint64n(span, &rng)
return min + T(v)
}
// Float32 generates a random 32-bit float value in the range [0, 1) using the hashPool.
// It retrieves a random 32-bit number from the hash pool, keeps the upper 24 bits,
// and converts it into a float32 by dividing by 2^24 to normalize
// the value into the range [0, 1).
func Float32() float32 {
const inv24 = float32(1.0 / (1 << 24))
return float32(DefaultHashPool.Sum32()>>8) * inv24
}
// Float64 generates a random 64-bit float value in the range [0, 1) using the hashPool.
// It retrieves a random 64-bit number from the hash pool, keeps the upper 53 bits,
// and converts it into a float64 by dividing by 2^53 to normalize
// the value into the range [0, 1).
func Float64() float64 {
const inv53 = float64(1.0 / (1 << 53))
return float64(DefaultHashPool.Sum64()>>11) * inv53
}