From 294989daf515d8cad63bb30a8a80e39a45766a80 Mon Sep 17 00:00:00 2001 From: apense Date: Thu, 11 Jun 2015 18:47:28 -0400 Subject: Updated random functions For Windows, `rand_s` has been available since Windows XP (see https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx). It gives a better quality random number in a larger range (the max is actually `0xffffffff`). --- lib/pure/math.nim | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pure/math.nim b/lib/pure/math.nim index a9e9010f6..6c03dee4f 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -202,8 +202,15 @@ when not defined(JS): ## computes x to power raised of y. # C procs: - proc srand(seed: cint) {.importc: "srand", header: "".} - proc rand(): cint {.importc: "rand", header: "".} + when defined(windows): + # The "secure" random, available from Windows XP + # https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx + proc rand_s(val: var cuint) {.importc: "rand_s", header: "".} + # To behave like the normal version + proc rand(): cuint = rand_s(result) + else: + proc srand(seed: cint) {.importc: "srand", header: "".} + proc rand(): cint {.importc: "rand", header: "".} when not defined(windows): proc srand48(seed: clong) {.importc: "srand48", header: "".} @@ -216,13 +223,14 @@ when not defined(JS): # importcing macros is extremely problematic # and because the value is publicly documented # on MSDN and very unlikely to change - const rand_max = 32767 + # See https://msdn.microsoft.com/en-us/library/296az74e.aspx + const rand_max = 4294967295 result = (float(rand()) / float(rand_max)) * max proc randomize() = randomize(cast[int](epochTime())) proc randomize(seed: int) = - srand(cint(seed)) + when declared(srand): srand(cint(seed)) # rand_s doesn't use srand when declared(srand48): srand48(seed) proc random(max: int): int = result = int(rand()) mod max -- cgit 1.4.1-2-gfad0 From 7fba7d934b04d7a602944c1a8d0785e6d6a34b9a Mon Sep 17 00:00:00 2001 From: apense Date: Thu, 11 Jun 2015 18:56:59 -0400 Subject: Discarded randomize for windows It actually doesn't use it because `rand_s` doesn't. --- lib/pure/math.nim | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 6c03dee4f..34070dd91 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -217,6 +217,12 @@ when not defined(JS): proc drand48(): float {.importc: "drand48", header: "".} proc random(max: float): float = result = drand48() * max + proc randomize() = + randomize(cast[int](epochTime())) + + proc randomize(seed: int) = + srand(cint(seed)) # rand_s doesn't use srand + srand48(seed) when defined(windows): proc random(max: float): float = # we are hardcodeing this because @@ -226,12 +232,9 @@ when not defined(JS): # See https://msdn.microsoft.com/en-us/library/296az74e.aspx const rand_max = 4294967295 result = (float(rand()) / float(rand_max)) * max - proc randomize() = - randomize(cast[int](epochTime())) - - proc randomize(seed: int) = - when declared(srand): srand(cint(seed)) # rand_s doesn't use srand - when declared(srand48): srand48(seed) + proc randomize() = discard + proc randomize(seed: int) = discard + proc random(max: int): int = result = int(rand()) mod max -- cgit 1.4.1-2-gfad0 From 4072a39c69f2711683604c94884b1536a7bd5c41 Mon Sep 17 00:00:00 2001 From: apense Date: Sun, 14 Jun 2015 21:16:39 -0400 Subject: Updated RNG for Visual C Can't test it, but it should work just fine. Can be extended to MinGW w/ GCC and other compilers sometime in the future --- lib/pure/math.nim | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 34070dd91..b91c7f0d8 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -202,9 +202,11 @@ when not defined(JS): ## computes x to power raised of y. # C procs: - when defined(windows): + when defined(vcc): # The "secure" random, available from Windows XP # https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx + # Present in some variants of MinGW but not enough to justify + # `when defined(windows)` yet proc rand_s(val: var cuint) {.importc: "rand_s", header: "".} # To behave like the normal version proc rand(): cuint = rand_s(result) @@ -217,23 +219,34 @@ when not defined(JS): proc drand48(): float {.importc: "drand48", header: "".} proc random(max: float): float = result = drand48() * max + else: + when defined(vcc): # Windows with Visual C + proc random(max: float): float = + # we are hardcoding this because + # importc-ing macros is extremely problematic + # and because the value is publicly documented + # on MSDN and very unlikely to change + # See https://msdn.microsoft.com/en-us/library/296az74e.aspx + const rand_max = 4294967295 # UINT_MAX + result = (float(rand()) / float(rand_max)) * max + proc randomize() = discard + proc randomize(seed: int) = discard + else: # Windows with another compiler + proc random(max: float): float = + # we are hardcoding this because + # importc-ing macros is extremely problematic + # and because the value is publicly documented + # on MSDN and very unlikely to change + const rand_max = 32767 + result = (float(rand()) / float(rand_max)) * max + + when not defined(vcc): # the above code for vcc uses `discard` instead + # this is either not Windows or is Windows without vcc proc randomize() = randomize(cast[int](epochTime())) - proc randomize(seed: int) = srand(cint(seed)) # rand_s doesn't use srand - srand48(seed) - when defined(windows): - proc random(max: float): float = - # we are hardcodeing this because - # importcing macros is extremely problematic - # and because the value is publicly documented - # on MSDN and very unlikely to change - # See https://msdn.microsoft.com/en-us/library/296az74e.aspx - const rand_max = 4294967295 - result = (float(rand()) / float(rand_max)) * max - proc randomize() = discard - proc randomize(seed: int) = discard + when declared(srand48): srand48(seed) proc random(max: int): int = result = int(rand()) mod max -- cgit 1.4.1-2-gfad0