summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-05-30 15:07:19 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-05-30 16:24:52 +0200
commit95bb19a57938b75a58169f816856be0cad4474b9 (patch)
tree231479f42aa725c0e11d0502905b617cb1f630b0
parent5575cfd3ec6124fd0447b00b3edc40c0a25f79da (diff)
downloadNim-95bb19a57938b75a58169f816856be0cad4474b9.tar.gz
moved random procs from math to its own module (breaking change)
-rw-r--r--lib/pure/collections/sequtils.nim2
-rw-r--r--lib/pure/concurrency/cpuload.nim2
-rw-r--r--lib/pure/httpclient.nim3
-rw-r--r--lib/pure/math.nim110
-rw-r--r--lib/pure/random.nim23
-rw-r--r--lib/pure/unittest.nim2
-rw-r--r--tests/js/tclosures.nim2
-rw-r--r--tests/parallel/twrong_refcounts.nim2
-rw-r--r--tests/stdlib/tmath.nim2
-rw-r--r--tests/stdlib/tunittest.nim2
-rw-r--r--tests/threads/ttryrecv.nim2
-rw-r--r--web/news.txt13
12 files changed, 43 insertions, 122 deletions
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index 0e3824a81..0817b38a3 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -657,7 +657,7 @@ template newSeqWith*(len: int, init: expr): expr =
   ##   seq2D[1][0] = true
   ##   seq2D[0][1] = true
   ##
-  ##   import math
+  ##   import random
   ##   var seqRand = newSeqWith(20, random(10))
   ##   echo seqRand
   var result {.gensym.} = newSeq[type(init)](len)
diff --git a/lib/pure/concurrency/cpuload.nim b/lib/pure/concurrency/cpuload.nim
index 22598b5c9..b0fd002ed 100644
--- a/lib/pure/concurrency/cpuload.nim
+++ b/lib/pure/concurrency/cpuload.nim
@@ -79,6 +79,8 @@ proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
   inc s.calls
 
 when not defined(testing) and isMainModule:
+  import random
+
   proc busyLoop() =
     while true:
       discard random(80)
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 040ce10da..d59b8ecfe 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -79,7 +79,8 @@
 ## constructor should be used for this purpose. However,
 ## currently only basic authentication is supported.
 
-import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math
+import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes,
+  math, random
 import asyncnet, asyncdispatch
 import nativesockets
 
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 2feaef097..ce418d72c 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -39,8 +39,6 @@ proc fac*(n: int): int {.noSideEffect.} =
 
 when defined(Posix) and not defined(haiku):
   {.passl: "-lm".}
-when not defined(js) and not defined(nimscript):
-  import times
 
 const
   PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
@@ -119,30 +117,6 @@ proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
   ## If `x` is empty, 0 is returned.
   for i in items(x): result = result + i
 
-proc random*(max: int): int {.benign.}
-  ## Returns a random number in the range 0..max-1. The sequence of
-  ## random number is always the same, unless `randomize` is called
-  ## which initializes the random number generator with a "random"
-  ## number, i.e. a tickcount.
-
-proc random*(max: float): float {.benign.}
-  ## Returns a random number in the range 0..<max. The sequence of
-  ## random number is always the same, unless `randomize` is called
-  ## which initializes the random number generator with a "random"
-  ## number, i.e. a tickcount. This has a 16-bit resolution on windows
-  ## and a 48-bit resolution on other platforms.
-
-when not defined(nimscript):
-  proc randomize*() {.benign.}
-    ## Initializes the random number generator with a "random"
-    ## number, i.e. a tickcount. Note: Does nothing for the JavaScript target,
-    ## as JavaScript does not support this. Nor does it work for NimScript.
-
-proc randomize*(seed: int) {.benign.}
-  ## Initializes the random number generator with a specific seed.
-  ## Note: Does nothing for the JavaScript target,
-  ## as JavaScript does not support this.
-
 {.push noSideEffect.}
 when not defined(JS):
   proc sqrt*(x: float32): float32 {.importc: "sqrtf", header: "<math.h>".}
@@ -239,57 +213,6 @@ when not defined(JS):
   proc tgamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
     ## The gamma function
 
-  # C procs:
-  when defined(vcc) and false:
-    # 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: "<stdlib.h>".}
-    # To behave like the normal version
-    proc rand(): cuint = rand_s(result)
-  else:
-    proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>".}
-    proc rand(): cint {.importc: "rand", header: "<stdlib.h>".}
-
-  when not defined(windows):
-    proc srand48(seed: clong) {.importc: "srand48", header: "<stdlib.h>".}
-    proc drand48(): float {.importc: "drand48", header: "<stdlib.h>".}
-    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
-    when not defined(nimscript):
-      proc randomize() =
-        randomize(cast[int](epochTime()))
-    proc randomize(seed: int) =
-      srand(cint(seed)) # rand_s doesn't use srand
-      when declared(srand48): srand48(seed)
-
-  proc random(max: int): int =
-    result = int(rand()) mod max
-
   proc trunc*(x: float32): float32 {.importc: "truncf", header: "<math.h>".}
   proc trunc*(x: float64): float64 {.importc: "trunc", header: "<math.h>".}
     ## Truncates `x` to the decimal point
@@ -319,17 +242,10 @@ when not defined(JS):
     ##  echo fmod(-2.5, 0.3) ## -0.1
 
 else:
-  proc mathrandom(): float {.importc: "Math.random", nodecl.}
   proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.}
   proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.}
   proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.}
   proc ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.}
-  proc random(max: int): int =
-    result = int(floor(mathrandom() * float(max)))
-  proc random(max: float): float =
-    result = float(mathrandom() * float(max))
-  proc randomize() = discard
-  proc randomize(seed: int) = discard
 
   proc sqrt*(x: float32): float32 {.importc: "Math.sqrt", nodecl.}
   proc sqrt*(x: float64): float64 {.importc: "Math.sqrt", nodecl.}
@@ -398,14 +314,6 @@ proc `mod`*[T: float32|float64](x, y: T): T =
   ##  echo (4.0 mod -3.1) # -2.2
   result = if y == 0.0: x else: x - y * (x/y).floor
 
-proc random*[T](x: Slice[T]): T =
-  ## For a slice `a .. b` returns a value in the range `a .. b-1`.
-  result = random(x.b - x.a) + x.a
-
-proc random*[T](a: openArray[T]): T =
-  ## returns a random element from the openarray `a`.
-  result = a[random(a.low..a.len)]
-
 {.pop.}
 {.pop.}
 
@@ -440,24 +348,6 @@ proc lcm*[T](x, y: T): T =
   x div gcd(x, y) * y
 
 when isMainModule and not defined(JS):
-  proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
-
-  # Verifies random seed initialization.
-  let seed = gettime(nil)
-  randomize(seed)
-  const SIZE = 10
-  var buf : array[0..SIZE, int]
-  # Fill the buffer with random values
-  for i in 0..SIZE-1:
-    buf[i] = random(high(int))
-  # Check that the second random calls are the same for each position.
-  randomize(seed)
-  for i in 0..SIZE-1:
-    assert buf[i] == random(high(int)), "non deterministic random seeding"
-
-  when not defined(testing):
-    echo "random values equal after reseeding"
-
   # Check for no side effect annotation
   proc mySqrt(num: float): float {.noSideEffect.} =
     return sqrt(num)
diff --git a/lib/pure/random.nim b/lib/pure/random.nim
index 5a4d45c38..c79f2f77f 100644
--- a/lib/pure/random.nim
+++ b/lib/pure/random.nim
@@ -69,6 +69,14 @@ proc random*(max: float): float {.benign.} =
   let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
   result = (cast[float](u) - 1.0) * max
 
+proc random*[T](x: Slice[T]): T =
+  ## For a slice `a .. b` returns a value in the range `a .. b-1`.
+  result = random(x.b - x.a) + x.a
+
+proc random*[T](a: openArray[T]): T =
+  ## returns a random element from the openarray `a`.
+  result = a[random(a.low..a.len)]
+
 proc randomize*(seed: int) {.benign.} =
   ## Initializes the random number generator with a specific seed.
   state.a0 = uint64(seed shr 16)
@@ -84,3 +92,18 @@ when not defined(nimscript):
     randomize(int times.getTime())
 
 {.pop.}
+
+when isMainModule:
+  proc main =
+    var occur: array[1000, int]
+
+    var x = 8234
+    for i in 0..100_000:
+      x = random(len(occur)) # myrand(x)
+      inc occur[x]
+    for i, oc in occur:
+      if oc < 69:
+        doAssert false, "too few occurances of " & $i
+      elif oc > 130:
+        doAssert false, "too many occurances of " & $i
+  main()
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index aca9d51e2..b83ec44ca 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -310,7 +310,7 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
   ##
   ## .. code-block:: nim
   ##
-  ##  import math
+  ##  import math, random
   ##  proc defectiveRobot() =
   ##    randomize()
   ##    case random(1..4)
diff --git a/tests/js/tclosures.nim b/tests/js/tclosures.nim
index c0d93814c..0ec4f4743 100644
--- a/tests/js/tclosures.nim
+++ b/tests/js/tclosures.nim
@@ -2,7 +2,7 @@ discard """
   action: run
 """
 
-import math, strutils
+import math, random, strutils
 const consolePrefix = "jsCallbacks"
 
 asm """
diff --git a/tests/parallel/twrong_refcounts.nim b/tests/parallel/twrong_refcounts.nim
index db32a96d8..57e0588a0 100644
--- a/tests/parallel/twrong_refcounts.nim
+++ b/tests/parallel/twrong_refcounts.nim
@@ -2,7 +2,7 @@ discard """
   output: "Success"
 """
 
-import math, threadPool
+import math, random, threadPool
 
 # ---
 
diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim
index 1ac9c8092..538582ba8 100644
--- a/tests/stdlib/tmath.nim
+++ b/tests/stdlib/tmath.nim
@@ -1,4 +1,4 @@
-import math
+import math, random
 import unittest
 import sets
 
diff --git a/tests/stdlib/tunittest.nim b/tests/stdlib/tunittest.nim
index 4b210c23b..73113ac68 100644
--- a/tests/stdlib/tunittest.nim
+++ b/tests/stdlib/tunittest.nim
@@ -26,7 +26,7 @@ test "unittest multiple requires":
   require(true)
 
 
-import math
+import math, random
 from strutils import parseInt
 proc defectiveRobot() =
   randomize()
diff --git a/tests/threads/ttryrecv.nim b/tests/threads/ttryrecv.nim
index be79fadae..4a98e6c27 100644
--- a/tests/threads/ttryrecv.nim
+++ b/tests/threads/ttryrecv.nim
@@ -4,7 +4,7 @@ discard """
 
 # bug #1816
 
-from math import random
+from random import random
 from os import sleep
 
 type PComm = ptr Channel[int]
diff --git a/web/news.txt b/web/news.txt
index 87896df3f..837f30f40 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -2,7 +2,7 @@
 News
 ====
 
-2016-XX-XX Version 0.13.1 released
+2016-XX-XX Version 0.14.0 released
 ==================================
 
 Changes affecting backwards compatibility
@@ -39,6 +39,9 @@ Changes affecting backwards compatibility
   you need that.
 - The ``json.%`` operator is now overloaded for ``object``, ``ref object`` and
   ``openarray[T]``.
+- The procs related to ``random`` number generation in ``math.nim`` have
+  been moved to its own ``random`` module and been reimplemented in pure
+  Nim.
 
 
 Library Additions
@@ -64,11 +67,13 @@ Language Additions
 
 - Nim now supports a ``.this`` pragma for more notational convenience.
 - Nim now supports a different ``using`` statement for more convenience.
-- Nim now supports ``partial`` object declarations to mitigate the problems
-  that arise when types are mutually dependent and yet should be kept in
-  different modules.
 - ``include`` statements are not restricted to top level statements anymore.
 
+..
+  - Nim now supports ``partial`` object declarations to mitigate the problems
+    that arise when types are mutually dependent and yet should be kept in
+    different modules.
+
 
 2016-01-27 Nim in Action is now available!
 ==========================================