Improve rand(bool) (#20045)

* Improve rand(bool)

* Use sign test instead of mod 2

* Use mod 2 again, as it works for js

* Use right shift as suggested by the authors of xoroshiro

* Update random.nim

* General case doesn't need any right shift it was correct to begin with

* Update random.nim

* add comment

Co-authored-by: flywind <43030857+xflywind@users.noreply.github.com>
This commit is contained in:
Antonis Geralis 2022-07-18 22:18:12 +03:00 • committed by GitHub
commit f34734ffb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -377,10 +377,12 @@ proc rand*[T: Ordinal](t: typedesc[T]): T =
assert rand(range[1..16]) in 1..16 assert rand(range[1..16]) in 1..16
# pending csources >= 1.4.0 or fixing https://github.com/timotheecour/Nim/issues/251#issuecomment-831599772, # pending csources >= 1.4.0 or fixing https://github.com/timotheecour/Nim/issues/251#issuecomment-831599772,
# use `runnableExamples("-r:off")` instead of `if false` # use `runnableExamples("-r:off")` instead of `if false`
when T is range or T is enum or T is bool: when T is range or T is enum:
result = rand(state, low(T)..high(T)) result = rand(state, low(T)..high(T))
elif T is bool:
result = state.next shr 63 == 1 # sign test, works on js
else: else:
result = cast[T](state.next) result = cast[T](state.next shr (64 - sizeof(T)*8))
proc sample*[T](r: var Rand; s: set[T]): T = proc sample*[T](r: var Rand; s: set[T]): T =
## Returns a random element from the set `s` using the given state. ## Returns a random element from the set `s` using the given state.