diff options
Diffstat (limited to '')
-rw-r--r-- | dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/rand/arith128_test.go | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/rand/arith128_test.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/rand/arith128_test.go new file mode 100644 index 0000000..eed655b --- /dev/null +++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/rand/arith128_test.go @@ -0,0 +1,126 @@ +// 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. + +package rand + +import ( + "math/big" + "math/rand" + "testing" +) + +var bigMaxUint64 = big.NewInt(0).SetUint64(maxUint64) + +func bigInt(xHi, xLo uint64) *big.Int { + b := big.NewInt(0).SetUint64(xHi) + b.Lsh(b, 64) + b.Or(b, big.NewInt(0).SetUint64(xLo)) + return b +} + +func splitBigInt(b *big.Int) (outHi, outLo uint64) { + outHi = big.NewInt(0).Rsh(b, 64).Uint64() + outLo = big.NewInt(0).And(b, bigMaxUint64).Uint64() + return +} + +func bigMulMod128bits(xHi, xLo, yHi, yLo uint64) (outHi, outLo uint64) { + bigX := bigInt(xHi, xLo) + bigY := bigInt(yHi, yLo) + return splitBigInt(bigX.Mul(bigX, bigY)) +} + +func bigAddMod128bits(xHi, xLo, yHi, yLo uint64) (outHi, outLo uint64) { + bigX := bigInt(xHi, xLo) + bigY := bigInt(yHi, yLo) + return splitBigInt(bigX.Add(bigX, bigY)) +} + +type arithTest struct { + xHi, xLo uint64 +} + +const ( + iLo = increment & maxUint64 + iHi = (increment >> 64) & maxUint64 +) + +var arithTests = []arithTest{ + {0, 0}, + {0, 1}, + {1, 0}, + {0, maxUint64}, + {maxUint64, 0}, + {maxUint64, maxUint64}, + // Randomly generated 64-bit integers. + {3757956613005209672, 17983933746665545631}, + {511324141977587414, 5626651684620191081}, + {1534313104606153588, 2415006486399353367}, + {6873586429837825902, 13854394671140464137}, + {6617134480561088940, 18421520694158684312}, +} + +func TestPCGAdd(t *testing.T) { + for i, test := range arithTests { + p := &PCGSource{ + low: test.xLo, + high: test.xHi, + } + p.add() + expectHi, expectLo := bigAddMod128bits(test.xHi, test.xLo, iHi, iLo) + if p.low != expectLo || p.high != expectHi { + t.Errorf("%d: got hi=%d lo=%d; expect hi=%d lo=%d", i, p.high, p.low, expectHi, expectLo) + } + } +} + +const ( + mLo = multiplier & maxUint64 + mHi = (multiplier >> 64) & maxUint64 +) + +func TestPCGMultiply(t *testing.T) { + for i, test := range arithTests { + p := &PCGSource{ + low: test.xLo, + high: test.xHi, + } + p.multiply() + expectHi, expectLo := bigMulMod128bits(test.xHi, test.xLo, mHi, mLo) + if p.low != expectLo || p.high != expectHi { + t.Errorf("%d: got hi=%d lo=%d; expect hi=%d lo=%d", i, p.high, p.low, expectHi, expectLo) + } + } +} + +func TestPCGMultiplyLong(t *testing.T) { + if testing.Short() { + return + } + for i := 0; i < 1e6; i++ { + low := rand.Uint64() + high := rand.Uint64() + p := &PCGSource{ + low: low, + high: high, + } + p.multiply() + expectHi, expectLo := bigMulMod128bits(high, low, mHi, mLo) + if p.low != expectLo || p.high != expectHi { + t.Fatalf("%d: (%d,%d): got hi=%d lo=%d; expect hi=%d lo=%d", i, high, low, p.high, p.low, expectHi, expectLo) + } + } +} + +func BenchmarkPCGMultiply(b *testing.B) { + low := rand.Uint64() + high := rand.Uint64() + p := &PCGSource{ + low: low, + high: high, + } + for i := 0; i < b.N; i++ { + p.multiply() + } +} |