random.nim: added shuffle proc; fixes 'mod' bias
This commit is contained in:
parent
9c47bb9cc0
commit
13649778c1
1 changed files with 12 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nim's Runtime Library
|
# Nim's Runtime Library
|
||||||
# (c) Copyright 2016 Andreas Rumpf
|
# (c) Copyright 2017 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -22,6 +22,8 @@ when defined(JS):
|
||||||
else:
|
else:
|
||||||
type ui = uint64
|
type ui = uint64
|
||||||
|
|
||||||
|
const randMax = 18_446_744_073_709_551_615u64
|
||||||
|
|
||||||
type
|
type
|
||||||
RandomGenState = object
|
RandomGenState = object
|
||||||
a0, a1: ui
|
a0, a1: ui
|
||||||
|
|
@ -72,7 +74,10 @@ proc random*(max: int): int {.benign.} =
|
||||||
## random number is always the same, unless `randomize` is called
|
## random number is always the same, unless `randomize` is called
|
||||||
## which initializes the random number generator with a "random"
|
## which initializes the random number generator with a "random"
|
||||||
## number, i.e. a tickcount.
|
## number, i.e. a tickcount.
|
||||||
result = int(next(state) mod uint64(max))
|
while true:
|
||||||
|
let x = next(state)
|
||||||
|
if x < randMax - (randMax mod uint64(max)):
|
||||||
|
return int(x mod uint64(max))
|
||||||
|
|
||||||
proc random*(max: float): float {.benign.} =
|
proc random*(max: float): float {.benign.} =
|
||||||
## Returns a random number in the range 0..<max. The sequence of
|
## Returns a random number in the range 0..<max. The sequence of
|
||||||
|
|
@ -99,6 +104,11 @@ proc randomize*(seed: int) {.benign.} =
|
||||||
state.a0 = ui(seed shr 16)
|
state.a0 = ui(seed shr 16)
|
||||||
state.a1 = ui(seed and 0xffff)
|
state.a1 = ui(seed and 0xffff)
|
||||||
|
|
||||||
|
proc shuffle*[T](x: var seq[T]) =
|
||||||
|
for i in countdown(x.high, 0):
|
||||||
|
let j = random(i + 1)
|
||||||
|
swap(x[i], x[j])
|
||||||
|
|
||||||
when not defined(nimscript):
|
when not defined(nimscript):
|
||||||
import times
|
import times
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue