github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/math/rand/gen_cooked.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build ignore
     6  
     7  // This program computes the value of rng_cooked in rng.go,
     8  // which is used for seeding all instances of rand.Source.
     9  // a 64bit and a 63bit version of the array is printed to
    10  // the standard output.
    11  
    12  package main
    13  
    14  import "fmt"
    15  
    16  const (
    17  	length = 607
    18  	tap    = 273
    19  	mask   = (1 << 63) - 1
    20  	a      = 48271
    21  	m      = (1 << 31) - 1
    22  	q      = 44488
    23  	r      = 3399
    24  )
    25  
    26  var (
    27  	rngVec          [length]int64
    28  	rngTap, rngFeed int
    29  )
    30  
    31  func seedrand(x int32) int32 {
    32  	hi := x / q
    33  	lo := x % q
    34  	x = a*lo - r*hi
    35  	if x < 0 {
    36  		x += m
    37  	}
    38  	return x
    39  }
    40  
    41  func srand(seed int32) {
    42  	rngTap = 0
    43  	rngFeed = length - tap
    44  	seed %= m
    45  	if seed < 0 {
    46  		seed += m
    47  	} else if seed == 0 {
    48  		seed = 89482311
    49  	}
    50  	x := seed
    51  	for i := -20; i < length; i++ {
    52  		x = seedrand(x)
    53  		if i >= 0 {
    54  			var u int64
    55  			u = int64(x) << 20
    56  			x = seedrand(x)
    57  			u ^= int64(x) << 10
    58  			x = seedrand(x)
    59  			u ^= int64(x)
    60  			rngVec[i] = u
    61  		}
    62  	}
    63  }
    64  
    65  func vrand() int64 {
    66  	rngTap--
    67  	if rngTap < 0 {
    68  		rngTap += length
    69  	}
    70  	rngFeed--
    71  	if rngFeed < 0 {
    72  		rngFeed += length
    73  	}
    74  	x := (rngVec[rngFeed] + rngVec[rngTap])
    75  	rngVec[rngFeed] = x
    76  	return x
    77  }
    78  
    79  func main() {
    80  	srand(1)
    81  	for i := uint64(0); i < 7.8e12; i++ {
    82  		vrand()
    83  	}
    84  	fmt.Printf("rngVec after 7.8e12 calls to vrand:\n%#v\n", rngVec)
    85  	for i := range rngVec {
    86  		rngVec[i] &= mask
    87  	}
    88  	fmt.Printf("lower 63bit of rngVec after 7.8e12 calls to vrand:\n%#v\n", rngVec)
    89  }