51 строка
1.2 KiB
Go
51 строка
1.2 KiB
Go
// Copyright 2017 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// This file validates that the calculation in Uint64n corrects for
|
|
// possible bias.
|
|
|
|
package rand
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
// modSource is used to probe the upper region of uint64 space. It
|
|
// generates values sequentially in [maxUint64-15,maxUint64]. With
|
|
// modEdge == 15 and maxUint64 == 1<<64-1 == 18446744073709551615,
|
|
// this means that Uint64n(10) will repeatedly probe the top range.
|
|
// We thus expect a bias to result unless the calculation in Uint64n
|
|
// gets the edge condition right. We test this by calling Uint64n 100
|
|
// times; the results should be perfectly evenly distributed across
|
|
// [0,10).
|
|
type modSource uint64
|
|
|
|
const modEdge = 15
|
|
|
|
func (m *modSource) Seed(uint64) {}
|
|
|
|
// Uint64 returns a non-pseudo-random 64-bit unsigned integer as a uint64.
|
|
func (m *modSource) Uint64() uint64 {
|
|
if *m > modEdge {
|
|
*m = 0
|
|
}
|
|
r := maxUint64 - *m
|
|
*m++
|
|
return uint64(r)
|
|
}
|
|
|
|
func TestUint64Modulo(t *testing.T) {
|
|
var src modSource
|
|
rng := New(&src)
|
|
var result [10]uint64
|
|
for i := 0; i < 100; i++ {
|
|
result[rng.Uint64n(10)]++
|
|
}
|
|
for _, r := range result {
|
|
if r != 10 {
|
|
t.Fatal(result)
|
|
}
|
|
}
|
|
}
|