diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-05-30 15:07:19 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-05-30 16:24:52 +0200 |
commit | 95bb19a57938b75a58169f816856be0cad4474b9 (patch) | |
tree | 231479f42aa725c0e11d0502905b617cb1f630b0 | |
parent | 5575cfd3ec6124fd0447b00b3edc40c0a25f79da (diff) | |
download | Nim-95bb19a57938b75a58169f816856be0cad4474b9.tar.gz |
moved random procs from math to its own module (breaking change)
-rw-r--r-- | lib/pure/collections/sequtils.nim | 2 | ||||
-rw-r--r-- | lib/pure/concurrency/cpuload.nim | 2 | ||||
-rw-r--r-- | lib/pure/httpclient.nim | 3 | ||||
-rw-r--r-- | lib/pure/math.nim | 110 | ||||
-rw-r--r-- | lib/pure/random.nim | 23 | ||||
-rw-r--r-- | lib/pure/unittest.nim | 2 | ||||
-rw-r--r-- | tests/js/tclosures.nim | 2 | ||||
-rw-r--r-- | tests/parallel/twrong_refcounts.nim | 2 | ||||
-rw-r--r-- | tests/stdlib/tmath.nim | 2 | ||||
-rw-r--r-- | tests/stdlib/tunittest.nim | 2 | ||||
-rw-r--r-- | tests/threads/ttryrecv.nim | 2 | ||||
-rw-r--r-- | web/news.txt | 13 |
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! ========================================== |