From 4925a60095f4aa415043c6ac99353419c0b2f72c Mon Sep 17 00:00:00 2001 From: Spiegel Date: Sat, 9 Mar 2024 17:55:53 +0900 Subject: [PATCH] Update for math/rand/v2 package --- README.md | 78 +++++++++++++++++++++---------------- Taskfile.yml | 2 +- benchmark/benchmark_test.go | 51 ++++++++++++------------ go.mod | 4 +- mt19937/example_test.go | 6 +-- mt19937/mt19937.go | 26 ++++++------- mt19937/mt19937_test.go | 14 +++---- prng.go | 50 ++++++++++-------------- prng_test.go | 15 ++----- sample/sample1.go | 10 ++--- sample/sample2.go | 9 +++-- sample/sample3.go | 32 ++++++++++++--- secure/README.md | 25 ------------ secure/secure.go | 74 ----------------------------------- 14 files changed, 155 insertions(+), 241 deletions(-) delete mode 100644 secure/README.md delete mode 100644 secure/secure.go diff --git a/README.md b/README.md index 58a59f8..532adc0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [goark/mt][mt] -- [Mersenne Twister]; Pseudo Random Number Generator, Implemented by [Golang] +# [goark/mt][github.com/goark/mt/v2] -- [Mersenne Twister]; Pseudo Random Number Generator, Implemented by [Golang][Go] [![check vulns](https://github.com/goark/mt/workflows/vulns/badge.svg)](https://github.com/goark/mt/actions) [![lint status](https://github.com/goark/mt/workflows/lint/badge.svg)](https://github.com/goark/mt/actions) @@ -7,36 +7,47 @@ This package is "[Mersenne Twister]" algorithm, implemented by pure [Go]. -- Compatible with [math/rand] standard package. -- Concurrency-safe (if it uses [mt].PRNG type) +- required Go 1.22 or later +- Compatible with [math/rand/v2] standard package. +- Concurrency-safe (if it uses [mt][github.com/goark/mt/v2].PRNG type) -**Migrated repository to [github.com/goark/mt][mt]** +**Migrated repository to [github.com/goark/mt][github.com/goark/mt/v2]** ## Usage -### Usage with [math/rand] Standard Package (not concurrency-safe) +### Import ```go +import "github.com/goark/mt/v2" +``` + +### Usage with [math/rand/v2] Standard Package (not concurrency-safe) + +```go +package main + import ( "fmt" - "math/rand" + "math/rand/v2" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2/mt19937" ) -fmt.Println(rand.New(mt19937.New(19650218)).Uint64()) -//Output: -//13735441942630277712 +func main() { + fmt.Println(rand.New(mt19937.New(19650218)).Uint64()) + //Output: + //13735441942630277712 +} ``` -### Usage of [mt].PRNG type (concurrency-safe version) +### Usage of [mt][github.com/goark/mt/v2].PRNG type (concurrency-safe version) ```go import ( "fmt" - "github.com/goark/mt" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2" + "github.com/goark/mt/v2/mt19937" ) fmt.Println(mt.New(mt19937.New(19650218)).Uint64()) @@ -47,30 +58,31 @@ fmt.Println(mt.New(mt19937.New(19650218)).Uint64()) #### Use [io].Reader interface ```go -package main - import ( + "encoding/binary" "fmt" + "math/rand/v2" "sync" - "github.com/goark/mt" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2" + "github.com/goark/mt/v2/mt19937" ) func main() { - prng := mt.New(mt19937.New(19650218)) wg := sync.WaitGroup{} + prng := mt.New(mt19937.New(rand.Int64())) for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() r := prng.NewReader() + buf := [8]byte{} for i := 0; i < 10000; i++ { - buf := [8]byte{} - _, err := r.Read(buf[:]) + ct, err := r.Read(buf[:]) if err != nil { return } + fmt.Println(binary.LittleEndian.Uint64(buf[:ct])) } }() } @@ -84,15 +96,16 @@ func main() { $ go test -bench Random -benchmem ./benchmark goos: linux goarch: amd64 -pkg: github.com/goark/mt/benchmark -BenchmarkRandomALFG-4 1000000000 0.0466 ns/op 0 B/op 0 allocs/op -BenchmarkRandomMT19917-4 1000000000 0.0649 ns/op 0 B/op 0 allocs/op -BenchmarkRandomALFGRand-4 1000000000 0.0720 ns/op 0 B/op 0 allocs/op -BenchmarkRandomMT19917Rand-4 1000000000 0.0862 ns/op 0 B/op 0 allocs/op -BenchmarkRandomALFGLocked-4 1000000000 0.172 ns/op 0 B/op 0 allocs/op -BenchmarkRandomMT19917Locked-4 1000000000 0.192 ns/op 0 B/op 0 allocs/op +pkg: github.com/goark/mt/v2/benchmark +cpu: AMD Ryzen 5 PRO 4650G with Radeon Graphics +BenchmarkRandomPCG-12 785103775 2.031 ns/op 0 B/op 0 allocs/op +BenchmarkRandomMT19917-12 338082381 3.551 ns/op 0 B/op 0 allocs/op +BenchmarkRandomPCGRand-12 359948874 3.288 ns/op 0 B/op 0 allocs/op +BenchmarkRandomMT19917Rand-12 325159622 3.687 ns/op 0 B/op 0 allocs/op +BenchmarkRandomChaCha8Locked-12 186311572 6.443 ns/op 0 B/op 0 allocs/op +BenchmarkRandomMT19917Locked-12 128465040 9.346 ns/op 0 B/op 0 allocs/op PASS -ok github.com/goark/mt/benchmark 6.895s +ok github.com/goark/mt/v2/benchmark 10.408s ``` ## License @@ -102,9 +115,8 @@ This package is licensed under MIT license. - [Commercial Use of Mersenne Twister](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/elicense.html) - [Mersenne Twisterの商業利用について](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/license.html) -[mt]: https://github.com/goark/mt "goark/mt: Mersenne Twister; Pseudo Random Number Generator, Implemented by Golang" -[Go]: https://golang.org/ "The Go Programming Language" -[Golang]: https://golang.org/ "The Go Programming Language" -[math/rand]: https://golang.org/pkg/math/rand/ "rand - The Go Programming Language" -[io]: https://golang.org/pkg/io/ "io - The Go Programming Language" +[github.com/goark/mt/v2]: https://github.com/goark/mt "goark/mt: Mersenne Twister; Pseudo Random Number Generator, Implemented by Golang" +[Go]: https://go.dev/ "The Go Programming Language" +[math/rand/v2]: https://pkg.go.dev/math/rand/v2 "rand package - math/rand/v2 - Go Packages" +[io]: https://pkg.go.dev/io "io package - io - Go Packages" [Mersenne Twister]: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html "Mersenne Twister: A random number generator (since 1997/10)" diff --git a/Taskfile.yml b/Taskfile.yml index 72ccbaa..3b57faf 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -18,7 +18,7 @@ tasks: - '**/*.go' prepare: - - go mod tidy -v -go=1.21 + - go mod tidy -v -go=1.22 clean: desc: Initialize module and build cache, and remake go.sum file. diff --git a/benchmark/benchmark_test.go b/benchmark/benchmark_test.go index edee73a..bc3f98f 100644 --- a/benchmark/benchmark_test.go +++ b/benchmark/benchmark_test.go @@ -1,66 +1,65 @@ package benchmark import ( - "math/rand" + "math/rand/v2" "testing" - "time" - "github.com/goark/mt" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2" + "github.com/goark/mt/v2/mt19937" ) -const count = 10000000 +var seed1, seed2, seed3 = rand.Uint64(), rand.Uint64(), rand.Int64() -func BenchmarkRandomALFG(b *testing.B) { - rnd := rand.NewSource(time.Now().UnixNano()).(rand.Source64) +func BenchmarkRandomPCG(b *testing.B) { + rnd := rand.NewPCG(seed1, seed2) b.ResetTimer() - for i := 0; i < count; i++ { - rnd.Uint64() + for i := 0; i < b.N; i++ { + _ = rnd.Uint64() } } func BenchmarkRandomMT19917(b *testing.B) { - rnd := mt19937.New(time.Now().UnixNano()) + rnd := mt19937.New(seed3) b.ResetTimer() - for i := 0; i < count; i++ { - rnd.Uint64() + for i := 0; i < b.N; i++ { + _ = rnd.Uint64() } } -func BenchmarkRandomALFGRand(b *testing.B) { - rnd := rand.New(rand.NewSource(time.Now().UnixNano())) +func BenchmarkRandomPCGRand(b *testing.B) { + rnd := rand.New(rand.NewPCG(seed1, seed2)) b.ResetTimer() - for i := 0; i < count; i++ { - rnd.Uint64() + for i := 0; i < b.N; i++ { + _ = rnd.Uint64() } } func BenchmarkRandomMT19917Rand(b *testing.B) { - rnd := rand.New(mt19937.New(time.Now().UnixNano())) + rnd := rand.New(mt19937.New(seed3)) b.ResetTimer() - for i := 0; i < count; i++ { - rnd.Uint64() + for i := 0; i < b.N; i++ { + _ = rnd.Uint64() } } -func BenchmarkRandomALFGLocked(b *testing.B) { +func BenchmarkRandomChaCha8Locked(b *testing.B) { b.ResetTimer() - for i := 0; i < count; i++ { - rand.Uint64() + for i := 0; i < b.N; i++ { + _ = rand.Uint64() } } func BenchmarkRandomMT19917Locked(b *testing.B) { - rnd := mt.New(mt19937.New(time.Now().UnixNano())) + rnd := mt.New(mt19937.New(seed3)) b.ResetTimer() - for i := 0; i < count; i++ { - rnd.Uint64() + for i := 0; i < b.N; i++ { + _ = rnd.Uint64() } } /* MIT License * - * Copyright 2019 Spiegel + * Copyright 2019-2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/go.mod b/go.mod index ae2a93a..23ef635 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ -module github.com/goark/mt +module github.com/goark/mt/v2 -go 1.21 +go 1.22 toolchain go1.22.1 diff --git a/mt19937/example_test.go b/mt19937/example_test.go index 96ac982..a95e539 100644 --- a/mt19937/example_test.go +++ b/mt19937/example_test.go @@ -2,9 +2,9 @@ package mt19937_test import ( "fmt" - "math/rand" + "math/rand/v2" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2/mt19937" ) func ExampleNew() { @@ -15,7 +15,7 @@ func ExampleNew() { /* MIT License * - * Copyright 2019,2020 Spiegel + * Copyright 2019-2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/mt19937/mt19937.go b/mt19937/mt19937.go index b39a840..bffdeab 100644 --- a/mt19937/mt19937.go +++ b/mt19937/mt19937.go @@ -1,7 +1,7 @@ package mt19937 import ( - "github.com/goark/mt" + "github.com/goark/mt/v2" ) const ( @@ -9,7 +9,7 @@ const ( mm = nn / 2 ) -//Source is a source of random numbers. +// Source is a source of random numbers. type Source struct { mt [nn]uint64 //The array for the state vector mti int //mti==nn+1 means mt[nn] is not initialized @@ -17,21 +17,21 @@ type Source struct { var _ mt.Source = (*Source)(nil) //Source is compatible with mt.Source interface -//New returns a new pseudo-random source seeded with the given value. +// New returns a new pseudo-random source seeded with the given value. func New(seed int64) *Source { rng := &Source{mt: [nn]uint64{}, mti: nn + 1} rng.Seed(seed) return rng } -//NewWithArray returns a new pseudo-random source seeded with the given values. +// NewWithArray returns a new pseudo-random source seeded with the given values. func NewWithArray(seeds []uint64) *Source { rng := &Source{mt: [nn]uint64{}, mti: nn + 1} rng.SeedArray(seeds) return rng } -//Seed initializes Source with a seed +// Seed initializes Source with a seed func (s *Source) Seed(seed int64) { if s == nil { return @@ -42,7 +42,7 @@ func (s *Source) Seed(seed int64) { } } -//SeedArray initializes Source with seeds array +// SeedArray initializes Source with seeds array func (s *Source) SeedArray(seeds []uint64) { if s == nil { return @@ -89,7 +89,7 @@ var ( matrixA = [2]uint64{0, 0xB5026F5AA96619E9} ) -//Uint64 generates a random number on [0, 2^64-1]-interval +// Uint64 generates a random number on [0, 2^64-1]-interval func (s *Source) Uint64() uint64 { if s == nil { return 0 @@ -120,12 +120,12 @@ func (s *Source) Uint64() uint64 { return x } -//Int63 generates a random number on [0, 2^63-1]-interval -func (s *Source) Int63() int64 { - return (int64)(s.Uint64() >> 1) -} +// // Int63 generates a random number on [0, 2^63-1]-interval +// func (s *Source) Int63() int64 { +// return (int64)(s.Uint64() >> 1) +// } -//Real generates a random number +// Real generates a random number // on [0,1)-real-interval if mode==1, // on (0,1)-real-interval if mode==2, // on [0,1]-real-interval others @@ -145,7 +145,7 @@ func (s *Source) Real(mode int) float64 { /* MIT License * - * Copyright 2019 Spiegel, fork from 64bit Mersenne Twister code "mt19937-64.c". + * Copyright 2019-2024 Spiegel, fork from 64bit Mersenne Twister code "mt19937-64.c". * (http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/mt64.html) * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/mt19937/mt19937_test.go b/mt19937/mt19937_test.go index 1bbc54c..09cd9eb 100644 --- a/mt19937/mt19937_test.go +++ b/mt19937/mt19937_test.go @@ -444,29 +444,29 @@ func TestMT(t *testing.T) { func TestEmpty(t *testing.T) { rnd := &Source{mt: [nn]uint64{}, mti: nn + 1} - r := rnd.Int63() - res := New(5489).Int63() + r := rnd.Uint64() + res := New(5489).Uint64() if r != res { t.Errorf(".Int63() = \"%v\", want \"%v\".", r, res) } rnd.SeedArray(nil) - r2 := rnd.Int63() - res2 := New(19650218).Int63() + r2 := rnd.Uint64() + res2 := New(19650218).Uint64() if r2 != res2 { t.Errorf(".Int63() = \"%v\", want \"%v\".", r2, res2) } } func TestNil(t *testing.T) { - r := (*Source)(nil).Int63() + r := (*Source)(nil).Uint64() if r != 0 { - t.Errorf(".Int63() = \"%v\", want \"%v\".", r, 0) + t.Errorf(".Uint64() = \"%v\", want \"%v\".", r, 0) } } /* MIT License * - * Copyright 2019,2020 Spiegel + * Copyright 2019-2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/prng.go b/prng.go index 3e0e968..730b428 100644 --- a/prng.go +++ b/prng.go @@ -1,41 +1,31 @@ package mt import ( - "math/rand" + "math/rand/v2" "sync" ) -//Source represents a source of uniformly-distributed +// Source represents a source of uniformly-distributed type Source interface { - rand.Source64 + rand.Source SeedArray([]uint64) Real(int) float64 } -//PRNG is class of pseudo random number generator. +// PRNG is class of pseudo random number generator. type PRNG struct { source Source mutex *sync.Mutex } -var _ rand.Source64 = (*PRNG)(nil) //PRNG is compatible with rand.Source and rand.Source64 interface +var _ rand.Source = (*PRNG)(nil) //PRNG is compatible with rand.Source and rand.Source64 interface -//New returns new PRNG instance +// New returns new PRNG instance func New(s Source) *PRNG { return &PRNG{source: s, mutex: &sync.Mutex{}} } -//Seed initializes Source.mt with a seed -func (prng *PRNG) Seed(seed int64) { - if prng == nil { - return - } - prng.mutex.Lock() - prng.source.Seed(seed) - prng.mutex.Unlock() -} - -//SeedArray initializes Source.mt with seeds array +// SeedArray initializes Source.mt with seeds array func (prng *PRNG) SeedArray(seeds []uint64) { if prng == nil { return @@ -45,7 +35,7 @@ func (prng *PRNG) SeedArray(seeds []uint64) { prng.mutex.Unlock() } -//Uint64 generates a random number on [0, 2^64-1]-interval +// Uint64 generates a random number on [0, 2^64-1]-interval func (prng *PRNG) Uint64() (n uint64) { if prng == nil { return 0 @@ -56,18 +46,18 @@ func (prng *PRNG) Uint64() (n uint64) { return } -//Int63 generates a random number on [0, 2^63-1]-interval -func (prng *PRNG) Int63() (n int64) { - if prng == nil { - return 0 - } - prng.mutex.Lock() - n = prng.source.Int63() - prng.mutex.Unlock() - return -} +// // Int63 generates a random number on [0, 2^63-1]-interval +// func (prng *PRNG) Int63() (n int64) { +// if prng == nil { +// return 0 +// } +// prng.mutex.Lock() +// n = int64(prng.source.Uint64() & rngMask) +// prng.mutex.Unlock() +// return +// } -//Real generates a random number +// Real generates a random number // on [0,1)-real-interval if mode==1, // on (0,1)-real-interval if mode==2, // on [0,1]-real-interval others @@ -81,7 +71,7 @@ func (prng *PRNG) Real(mode int) (f float64) { return } -//NewReader returns new Reader instance. +// NewReader returns new Reader instance. func (prng *PRNG) NewReader() *Reader { return &Reader{prng: prng} } diff --git a/prng_test.go b/prng_test.go index 7a70efc..81b9501 100644 --- a/prng_test.go +++ b/prng_test.go @@ -10,38 +10,29 @@ import ( func TestNil(t *testing.T) { prng := (*PRNG)(nil) - prng.Seed(0) + // prng.Seed(0) prng.SeedArray(nil) if prng.Uint64() != 0 { t.Errorf("PRNG.Uint64() = %v, want %v.", prng.Uint64(), 0) } - if prng.Int63() != 0 { - t.Errorf("PRNG.Int63() = %v, want %v.", prng.Int63(), 0) - } if prng.Real(0) != 0.0 { t.Errorf("PRNG.Real() = %v, want %v.", prng.Real(0), 0.0) } } -//mockup for test +// mockup for test type testSource struct{} -func (t *testSource) Seed(seed int64) {} func (t *testSource) SeedArray(seeds []uint64) {} func (t *testSource) Uint64() uint64 { return 123456 } -func (t *testSource) Int63() int64 { return 654321 } func (t *testSource) Real(mode int) float64 { return 0.123456 } func TestPRNG(t *testing.T) { prng := New(&testSource{}) - prng.Seed(0) //no panic prng.SeedArray(nil) //no panic if prng.Uint64() != 123456 { t.Errorf("PRNG.Uint64() = %v, want %v.", prng.Uint64(), 123456) } - if prng.Int63() != 654321 { - t.Errorf("PRNG.Int63() = %v, want %v.", prng.Int63(), 654321) - } if prng.Real(0) != 0.123456 { t.Errorf("PRNG.Real() = %v, want %v.", prng.Real(0), 0.123456) } @@ -107,7 +98,7 @@ func TestNilReader(t *testing.T) { /* MIT License * - * Copyright 2019,2020 Spiegel + * Copyright 2019-2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/sample/sample1.go b/sample/sample1.go index 8413c18..628dc59 100644 --- a/sample/sample1.go +++ b/sample/sample1.go @@ -6,17 +6,17 @@ package main import ( "encoding/binary" "fmt" + "math/rand/v2" "sync" - "time" - "github.com/goark/mt" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2" + "github.com/goark/mt/v2/mt19937" ) func main() { //start := time.Now() wg := sync.WaitGroup{} - prng := mt.New(mt19937.New(time.Now().UnixNano())) + prng := mt.New(mt19937.New(rand.Int64())) for i := 0; i < 1000; i++ { wg.Add(1) go func() { @@ -38,7 +38,7 @@ func main() { /* MIT License * - * Copyright 2019 Spiegel + * Copyright 2019-2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/sample/sample2.go b/sample/sample2.go index 93f8bdf..1e55151 100644 --- a/sample/sample2.go +++ b/sample/sample2.go @@ -5,17 +5,18 @@ package main import ( "fmt" + stdrand "math/rand/v2" "sync" "time" - "github.com/goark/mt" - "github.com/goark/mt/mt19937" + "github.com/goark/mt/v2" + "github.com/goark/mt/v2/mt19937" ) func main() { start := time.Now() wg := sync.WaitGroup{} - prng := mt.New(mt19937.New(time.Now().UnixNano())) + prng := mt.New(mt19937.New(stdrand.Int64())) for i := 0; i < 1000; i++ { wg.Add(1) go func() { @@ -31,7 +32,7 @@ func main() { /* MIT License * - * Copyright 2019 Spiegel + * Copyright 2019-2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/sample/sample3.go b/sample/sample3.go index 76198cd..35b3209 100644 --- a/sample/sample3.go +++ b/sample/sample3.go @@ -5,20 +5,40 @@ package main import ( "fmt" - "math/rand" + "math" + "math/rand/v2" - "github.com/goark/mt" - "github.com/goark/mt/secure" + "github.com/goark/mt/v2/mt19937" ) func main() { - fmt.Println(rand.New(secure.Source{}).Uint64()) - fmt.Println(mt.New(secure.Source{}).Uint64()) + rnd := rand.New(mt19937.New(rand.Int64())) + points := []float64{} + max := 0.0 + min := 1.0 + sum := 0.0 + for range 10000 { + point := rnd.NormFloat64() + points = append(points, point) + min = math.Min(min, point) + max = math.Max(max, point) + sum += point + } + n := float64(len(points)) + ave := sum / n + d2 := 0.0 + for _, p := range points { + d2 += (p - ave) * (p - ave) + } + fmt.Println(" minimum: ", min) + fmt.Println(" maximum: ", max) + fmt.Println(" average: ", ave) + fmt.Println("standard deviation: ", math.Sqrt(d2/n)) } /* MIT License * - * Copyright 2021 Spiegel + * Copyright 2024 Spiegel * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/secure/README.md b/secure/README.md deleted file mode 100644 index fb0c554..0000000 --- a/secure/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# About "secure.Source" type - -`secure.Source` type is wrapper of crypto/rand package. - -## Usage - -```go -//go:build run -// +build run - -package main - -import ( - "fmt" - "math/rand" - - "github.com/goark/mt" - "github.com/goark/mt/secure" -) - -func main() { - fmt.Println(rand.New(secure.Source{}).Uint64()) - fmt.Println(mt.New(secure.Source{}).Uint64()) -} -``` diff --git a/secure/secure.go b/secure/secure.go deleted file mode 100644 index d75d3d8..0000000 --- a/secure/secure.go +++ /dev/null @@ -1,74 +0,0 @@ -package secure - -import ( - "crypto/rand" - "encoding/binary" - - "github.com/goark/mt" -) - -// Source is random source for mt.Source interface. -type Source struct{} - -var _ mt.Source = (*Source)(nil) //Source is compatible with mt.Source interface - -// Seed method is dummy function for rand.Source interface. -func (s Source) Seed(seed int64) {} - -// SeedArray method is dummy function for mt.Source interface. -func (s Source) SeedArray([]uint64) {} - -// Read method generates random bytes, using crypto/rand.Read() function. -func (s Source) Read(buf []byte) (int, error) { - return rand.Read(buf) -} - -// Uint64 method generates a random number in the range [0, 1<<64). -func (s Source) Uint64() uint64 { - b := [8]byte{} - ct, _ := s.Read(b[:]) - return binary.BigEndian.Uint64(b[:ct]) -} - -// Int63 method generates a random number in the range [0, 1<<63). -func (s Source) Int63() int64 { - return (int64)(s.Uint64() >> 1) -} - -//Real generates a random number -// on [0,1)-real-interval if mode==1, -// on (0,1)-real-interval if mode==2, -// on [0,1]-real-interval others -func (s Source) Real(mode int) float64 { - switch mode { - case 1: //generates a random number on [0,1)-real-interval - return (float64)(s.Uint64()>>11) * (1.0 / 9007199254740991.0) - case 2: //generates a random number on (0,1)-real-interval - return (float64)(s.Uint64()>>11) * (1.0 / 9007199254740992.0) - default: //generates a random number on [0,1]-real-interval - return ((float64)(s.Uint64()>>12) + 0.5) * (1.0 / 4503599627370496.0) - } -} - -/* MIT License - * - * Copyright 2021 Spiegel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */