The Go Programming Language

Source file src/pkg/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	func (r *Rand) Int63n(n int64) int64 {
    53		if n <= 0 {
    54			return 0
    55		}
    56		max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
    57		v := r.Int63()
    58		for v > max {
    59			v = r.Int63()
    60		}
    61		return v % n
    62	}
    63	
    64	// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
    65	func (r *Rand) Int31n(n int32) int32 {
    66		if n <= 0 {
    67			return 0
    68		}
    69		max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
    70		v := r.Int31()
    71		for v > max {
    72			v = r.Int31()
    73		}
    74		return v % n
    75	}
    76	
    77	// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
    78	func (r *Rand) Intn(n int) int {
    79		if n <= 1<<31-1 {
    80			return int(r.Int31n(int32(n)))
    81		}
    82		return int(r.Int63n(int64(n)))
    83	}
    84	
    85	// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
    86	func (r *Rand) Float64() float64 { return float64(r.Int63()) / (1 << 63) }
    87	
    88	// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
    89	func (r *Rand) Float32() float32 { return float32(r.Float64()) }
    90	
    91	// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
    92	func (r *Rand) Perm(n int) []int {
    93		m := make([]int, n)
    94		for i := 0; i < n; i++ {
    95			m[i] = i
    96		}
    97		for i := 0; i < n; i++ {
    98			j := r.Intn(i + 1)
    99			m[i], m[j] = m[j], m[i]
   100		}
   101		return m
   102	}
   103	
   104	/*
   105	 * Top-level convenience functions
   106	 */
   107	
   108	var globalRand = New(&lockedSource{src: NewSource(1)})
   109	
   110	// Seed uses the provided seed value to initialize the generator to a deterministic state.
   111	func Seed(seed int64) { globalRand.Seed(seed) }
   112	
   113	// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
   114	func Int63() int64 { return globalRand.Int63() }
   115	
   116	// Uint32 returns a pseudo-random 32-bit value as a uint32.
   117	func Uint32() uint32 { return globalRand.Uint32() }
   118	
   119	// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
   120	func Int31() int32 { return globalRand.Int31() }
   121	
   122	// Int returns a non-negative pseudo-random int.
   123	func Int() int { return globalRand.Int() }
   124	
   125	// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
   126	func Int63n(n int64) int64 { return globalRand.Int63n(n) }
   127	
   128	// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
   129	func Int31n(n int32) int32 { return globalRand.Int31n(n) }
   130	
   131	// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
   132	func Intn(n int) int { return globalRand.Intn(n) }
   133	
   134	// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
   135	func Float64() float64 { return globalRand.Float64() }
   136	
   137	// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
   138	func Float32() float32 { return globalRand.Float32() }
   139	
   140	// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
   141	func Perm(n int) []int { return globalRand.Perm(n) }
   142	
   143	// NormFloat64 returns a normally distributed float64 in the range
   144	// [-math.MaxFloat64, +math.MaxFloat64] with
   145	// standard normal distribution (mean = 0, stddev = 1).
   146	// To produce a different normal distribution, callers can
   147	// adjust the output using:
   148	//
   149	//  sample = NormFloat64() * desiredStdDev + desiredMean
   150	//
   151	func NormFloat64() float64 { return globalRand.NormFloat64() }
   152	
   153	// ExpFloat64 returns an exponentially distributed float64 in the range
   154	// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
   155	// (lambda) is 1 and whose mean is 1/lambda (1).
   156	// To produce a distribution with a different rate parameter,
   157	// callers can adjust the output using:
   158	//
   159	//  sample = ExpFloat64() / desiredRateParameter
   160	//
   161	func ExpFloat64() float64 { return globalRand.ExpFloat64() }
   162	
   163	type lockedSource struct {
   164		lk  sync.Mutex
   165		src Source
   166	}
   167	
   168	func (r *lockedSource) Int63() (n int64) {
   169		r.lk.Lock()
   170		n = r.src.Int63()
   171		r.lk.Unlock()
   172		return
   173	}
   174	
   175	func (r *lockedSource) Seed(seed int64) {
   176		r.lk.Lock()
   177		r.src.Seed(seed)
   178		r.lk.Unlock()
   179	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.