src/pkg/math/rand/rand.go - The Go Programming Language

Golang

Source file src/pkg/math/rand/rand.go

     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	// Package rand implements pseudo-random number generators.
     6	package rand
     7	
     8	import "sync"
     9	
    10	// A Source represents a source of uniformly-distributed
    11	// pseudo-random int64 values in the range [0, 1<<63).
    12	type Source interface {
    13		Int63() int64
    14		Seed(seed int64)
    15	}
    16	
    17	// NewSource returns a new pseudo-random Source seeded with the given value.
    18	func NewSource(seed int64) Source {
    19		var rng rngSource
    20		rng.Seed(seed)
    21		return &rng
    22	}
    23	
    24	// A Rand is a source of random numbers.
    25	type Rand struct {
    26		src Source
    27	}
    28	
    29	// New returns a new Rand that uses random values from src
    30	// to generate other random values.
    31	func New(src Source) *Rand { return &Rand{src} }
    32	
    33	// Seed uses the provided seed value to initialize the generator to a deterministic state.
    34	func (r *Rand) Seed(seed int64) { r.src.Seed(seed) }
    35	
    36	// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
    37	func (r *Rand) Int63() int64 { return r.src.Int63() }
    38	
    39	// Uint32 returns a pseudo-random 32-bit value as a uint32.
    40	func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) }
    41	
    42	// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
    43	func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) }
    44	
    45	// Int returns a non-negative pseudo-random int.
    46	func (r *Rand) Int() int {
    47		u := uint(r.Int63())
    48		return int(u << 1 >> 1) // clear sign bit if int == int32
    49	}
    50	
    51	// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
    52	// It panics if n <= 0.
    53	func (r *Rand) Int63n(n int64) int64 {
    54		if n <= 0 {
    55			panic("invalid argument to Int63n")
    56		}
    57		max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
    58		v := r.Int63()
    59		for v > max {
    60			v = r.Int63()
    61		}
    62		return v % n
    63	}
    64	
    65	// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
    66	// It panics if n <= 0.
    67	func (r *Rand) Int31n(n int32) int32 {
    68		if n <= 0 {
    69			panic("invalid argument to Int31n")
    70		}
    71		max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
    72		v := r.Int31()
    73		for v > max {
    74			v = r.Int31()
    75		}
    76		return v % n
    77	}
    78	
    79	// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
    80	// It panics if n <= 0.
    81	func (r *Rand) Intn(n int) int {
    82		if n <= 0 {
    83			panic("invalid argument to Intn")
    84		}
    85		if n <= 1<<31-1 {
    86			return int(r.Int31n(int32(n)))
    87		}
    88		return int(r.Int63n(int64(n)))
    89	}
    90	
    91	// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
    92	func (r *Rand) Float64() float64 { return float64(r.Int63()) / (1 << 63) }
    93	
    94	// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
    95	func (r *Rand) Float32() float32 { return float32(r.Float64()) }
    96	
    97	// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
    98	func (r *Rand) Perm(n int) []int {
    99		m := make([]int, n)
   100		for i := 0; i < n; i++ {
   101			m[i] = i
   102		}
   103		for i := 0; i < n; i++ {
   104			j := r.Intn(i + 1)
   105			m[i], m[j] = m[j], m[i]
   106		}
   107		return m
   108	}
   109	
   110	/*
   111	 * Top-level convenience functions
   112	 */
   113	
   114	var globalRand = New(&lockedSource{src: NewSource(1)})
   115	
   116	// Seed uses the provided seed value to initialize the generator to a
   117	// deterministic state. If Seed is not called, the generator behaves as
   118	// if seeded by Seed(1).
   119	func Seed(seed int64) { globalRand.Seed(seed) }
   120	
   121	// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
   122	func Int63() int64 { return globalRand.Int63() }
   123	
   124	// Uint32 returns a pseudo-random 32-bit value as a uint32.
   125	func Uint32() uint32 { return globalRand.Uint32() }
   126	
   127	// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
   128	func Int31() int32 { return globalRand.Int31() }
   129	
   130	// Int returns a non-negative pseudo-random int.
   131	func Int() int { return globalRand.Int() }
   132	
   133	// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
   134	// It panics if n <= 0.
   135	func Int63n(n int64) int64 { return globalRand.Int63n(n) }
   136	
   137	// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
   138	// It panics if n <= 0.
   139	func Int31n(n int32) int32 { return globalRand.Int31n(n) }
   140	
   141	// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
   142	// It panics if n <= 0.
   143	func Intn(n int) int { return globalRand.Intn(n) }
   144	
   145	// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
   146	func Float64() float64 { return globalRand.Float64() }
   147	
   148	// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
   149	func Float32() float32 { return globalRand.Float32() }
   150	
   151	// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
   152	func Perm(n int) []int { return globalRand.Perm(n) }
   153	
   154	// NormFloat64 returns a normally distributed float64 in the range
   155	// [-math.MaxFloat64, +math.MaxFloat64] with
   156	// standard normal distribution (mean = 0, stddev = 1).
   157	// To produce a different normal distribution, callers can
   158	// adjust the output using:
   159	//
   160	//  sample = NormFloat64() * desiredStdDev + desiredMean
   161	//
   162	func NormFloat64() float64 { return globalRand.NormFloat64() }
   163	
   164	// ExpFloat64 returns an exponentially distributed float64 in the range
   165	// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
   166	// (lambda) is 1 and whose mean is 1/lambda (1).
   167	// To produce a distribution with a different rate parameter,
   168	// callers can adjust the output using:
   169	//
   170	//  sample = ExpFloat64() / desiredRateParameter
   171	//
   172	func ExpFloat64() float64 { return globalRand.ExpFloat64() }
   173	
   174	type lockedSource struct {
   175		lk  sync.Mutex
   176		src Source
   177	}
   178	
   179	func (r *lockedSource) Int63() (n int64) {
   180		r.lk.Lock()
   181		n = r.src.Int63()
   182		r.lk.Unlock()
   183		return
   184	}
   185	
   186	func (r *lockedSource) Seed(seed int64) {
   187		r.lk.Lock()
   188		r.src.Seed(seed)
   189		r.lk.Unlock()
   190	}