From 33cabeb04d4dc00f4edf40096f790b510f915dd9 Mon Sep 17 00:00:00 2001
From: Simon Hafner <hafnersimon@gmail.com>
Date: Wed, 5 Sep 2012 17:01:39 -0500
Subject: + random number generator for floats and slices - with tests

I also took the liberty to unify the API between ECMAScript and C.
---
 lib/pure/math.nim | 48 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 34 insertions(+), 14 deletions(-)

(limited to 'lib/pure/math.nim')

diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 587671165..d20fbc2ca 100755
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -123,17 +123,22 @@ proc variance*(x: openarray[float]): float {.noSideEffect.} =
     result = result + diff*diff
   result = result / toFloat(len(x))
 
-when not defined(ECMAScript):
-  proc random*(max: int): int
-    ## 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 randomize*()
-    ## initializes the random number generator with a "random"
-    ## number, i.e. a tickcount. Note: Does nothing for the ECMAScript target,
-    ## as ECMAScript does not support this.
+proc random*(max: int): int
+  ## 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
+  ## 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.
+proc randomize*()
+  ## initializes the random number generator with a "random"
+  ## number, i.e. a tickcount. Note: Does nothing for the ECMAScript target,
+  ## as ECMAScript does not support this.
   
+when not defined(ECMAScript):
   proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
     ## computes the square root of `x`.
   
@@ -179,10 +184,19 @@ when not defined(ECMAScript):
   # C procs:
   proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
   proc srand(seed: cint) {.importc: "srand", nodecl.}
+  proc srand48(seed: cint) {.importc: "srand48", nodecl.}
   proc rand(): cint {.importc: "rand", nodecl.}
+  proc drand48(): float {.importc: "drand48", nodecl.}
     
-  proc randomize() = srand(gettime(nil))
-  proc random(max: int): int = return int(rand()) mod max
+  var uniqueCounter: int = 0
+  proc randomize() =
+    srand(gettime(nil) + cint(uniqueCounter))
+    srand48(gettime(nil) + cint(uniqueCounter))
+    atomicInc(uniqueCounter)
+  proc random(max: int): int =
+    result = int(rand()) mod max
+  proc random(max: float): float =
+    result = drand48() * max
 
   proc trunc*(x: float): float {.importc: "trunc", nodecl.}
   proc floor*(x: float): float {.importc: "floor", nodecl.}
@@ -194,8 +208,11 @@ else:
   proc mathrandom(): float {.importc: "Math.random", nodecl.}
   proc floor*(x: float): float {.importc: "Math.floor", nodecl.}
   proc ceil*(x: float): float {.importc: "Math.ceil", nodecl.}
-  proc random*(max: int): int = return int(floor(mathrandom() * float(max)))
-  proc randomize*() = nil
+  proc random(max: int): int =
+    result = int(floor(mathrandom() * float(max)))
+  proc random(max: float): float =
+    result = float(mathrandom() * float(max))
+  proc randomize() = nil
   
   proc sqrt*(x: float): float {.importc: "Math.sqrt", nodecl.}
   proc ln*(x: float): float {.importc: "Math.log", nodecl.}
@@ -235,6 +252,9 @@ else:
 proc `mod`*(x, y: float): float =
   result = if y == 0.0: x else: x - y * (x/y).floor
 
+proc random*[T](x: TSlice[T]): T =
+  result = random(x.b - x.a) + x.a
+  
 type
   TRunningStat* {.pure,final.} = object  ## an accumulator for statistical data
     n*: int                              ## number of pushed data
-- 
cgit 1.4.1-2-gfad0

ew DeVault &lt;sir@cmpwn.com&gt;  2018-01-31 21:18:21 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-31 21:18:21 -0500

Improve logging' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=a21afdaa6bab8f6d05bbe9272700eef571548a59'>a21afda</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=1710c9054898e820700d673e21e7c7a90a3f67b1'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 21:24:50 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 21:31:36 -0500

Parse account configuration' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=b5d5e0dbedee34bd5d3edf13616f055d4f227d36'>b5d5e0d</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=6394e386c2a88c3b376cd422a7b7ce5ae7534984'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-05-20 19:20:20 -0400
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-05-20 19:28:04 -0400

Load IMAP worker for imap+insecure' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=2dc436555d8bfa6f2409173d87cd0fec2b2385cf'>2dc4365</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=cc90cd21610e7c78bc2cd9b04840fa1266617e6f'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Reto Brunner &lt;reto@labrat.space&gt;  2019-07-18 06:25:42 +0200
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-07-19 15:37:55 -0400

Register worker in init.' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=6fed04bb9fa43d3886d47d0c845d32fff11569b5'>6fed04b</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=66a9052f0fa8d2caf0d82435241b10e9ba8665b2'>^</a>


</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 20:39:00 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 20:39:00 -0500

Initial pass on worker/UI message passing' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=6394e386c2a88c3b376cd422a7b7ce5ae7534984'>6394e38</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=7d0edcc9e7ecdedb8cabafac1167581d7205596e'>^</a>

</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 20:39:00 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 20:39:00 -0500

Initial pass on worker/UI message passing' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=6394e386c2a88c3b376cd422a7b7ce5ae7534984'>6394e38</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=7d0edcc9e7ecdedb8cabafac1167581d7205596e'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-02-01 18:42:03 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-02-01 18:42:03 -0500

Reduce boilerplate in worker/UI' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=d24e4712a45e03d79fa1ccb71d00c5b830d5a305'>d24e471</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=ee73c419507ef74a78ddd6a3466b605cba140b68'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  emersion &lt;contact@emersion.fr&gt;  2018-01-10 17:19:45 +0100
committer  Drew DeVault &lt;ddevault@vistarmedia.com&gt;  2018-01-10 11:20:41 -0500

Misc idiomatic fixes' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=a0be5e80256b98237241b2f3d7825484e7a9c964'>a0be5e8</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=305446abfd66e85fe2c46cb4a07a3abb9fa809a4'>^</a>

</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 21:24:50 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 21:31:36 -0500

Parse account configuration' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=b5d5e0dbedee34bd5d3edf13616f055d4f227d36'>b5d5e0d</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=6394e386c2a88c3b376cd422a7b7ce5ae7534984'>^</a>

</pre></div><div class='alt'><pre><span class='oid'><a title='author  Simon Ser &lt;contact@emersion.fr&gt;  2019-04-27 15:56:38 +0000
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-04-27 14:28:26 -0400

worker/types: fix Worker.Callbacks race condition' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=9ef2a57b51601cc0e18824bbfe8026891da1a38d'>9ef2a57</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=2159eb876e7e04e81f65e64b1d742ad832890289'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-05-20 19:20:20 -0400
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-05-20 19:28:04 -0400

Load IMAP worker for imap+insecure' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=2dc436555d8bfa6f2409173d87cd0fec2b2385cf'>2dc4365</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=cc90cd21610e7c78bc2cd9b04840fa1266617e6f'>^</a>




</pre></div><div class='alt'><pre><span class='oid'><a title='author  Reto Brunner &lt;reto@labrat.space&gt;  2019-07-18 06:25:42 +0200
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-07-19 15:37:55 -0400

Register worker in init.' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=6fed04bb9fa43d3886d47d0c845d32fff11569b5'>6fed04b</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=66a9052f0fa8d2caf0d82435241b10e9ba8665b2'>^</a>


</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 21:24:50 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 21:31:36 -0500

Parse account configuration' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=b5d5e0dbedee34bd5d3edf13616f055d4f227d36'>b5d5e0d</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=6394e386c2a88c3b376cd422a7b7ce5ae7534984'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Reto Brunner &lt;reto@labrat.space&gt;  2019-07-18 06:25:42 +0200
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2019-07-19 15:37:55 -0400

Register worker in init.' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=6fed04bb9fa43d3886d47d0c845d32fff11569b5'>6fed04b</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=66a9052f0fa8d2caf0d82435241b10e9ba8665b2'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-02-01 18:42:03 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-02-01 18:42:03 -0500

Reduce boilerplate in worker/UI' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=d24e4712a45e03d79fa1ccb71d00c5b830d5a305'>d24e471</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=ee73c419507ef74a78ddd6a3466b605cba140b68'>^</a>
</pre></div><div class='alt'><pre><span class='oid'><a title='author  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 20:39:00 -0500
committer  Drew DeVault &lt;sir@cmpwn.com&gt;  2018-01-09 20:39:00 -0500

Initial pass on worker/UI message passing' href='/akspecs/aerc/commit/worker/worker.go?h=0.4.0&amp;id=6394e386c2a88c3b376cd422a7b7ce5ae7534984'>6394e38</a></span> <a title='Blame the previous revision' href='/akspecs/aerc/blame/worker/worker.go?h=0.4.0&amp;id=7d0edcc9e7ecdedb8cabafac1167581d7205596e'>^</a>
</pre></div></td>
<td class='linenumbers'><div class='alt'><pre><a id='n1' href='#n1'>1</a>
<a id='n2' href='#n2'>2</a>
<a id='n3' href='#n3'>3</a>
</pre></div><div class='alt'><pre><a id='n4' href='#n4'>4</a>
</pre></div><div class='alt'><pre><a id='n5' href='#n5'>5</a>
</pre></div><div class='alt'><pre><a id='n6' href='#n6'>6</a>
</pre></div><div class='alt'><pre><a id='n7' href='#n7'>7</a>
</pre></div><div class='alt'><pre><a id='n8' href='#n8'>8</a>
<a id='n9' href='#n9'>9</a>
<a id='n10' href='#n10'>10</a>
</pre></div><div class='alt'><pre><a id='n11' href='#n11'>11</a>
<a id='n12' href='#n12'>12</a>
</pre></div><div class='alt'><pre><a id='n13' href='#n13'>13</a>
</pre></div><div class='alt'><pre><a id='n14' href='#n14'>14</a>
</pre></div><div class='alt'><pre><a id='n15' href='#n15'>15</a>
<a id='n16' href='#n16'>16</a>
</pre></div><div class='alt'><pre><a id='n17' href='#n17'>17</a>
<a id='n18' href='#n18'>18</a>
</pre></div><div class='alt'><pre><a id='n19' href='#n19'>19</a>
</pre></div><div class='alt'><pre><a id='n20' href='#n20'>20</a>
<a id='n21' href='#n21'>21</a>
<a id='n22' href='#n22'>22</a>
<a id='n23' href='#n23'>23</a>
<a id='n24' href='#n24'>24</a>
</pre></div><div class='alt'><pre><a id='n25' href='#n25'>25</a>
<a id='n26' href='#n26'>26</a>
<a id='n27' href='#n27'>27</a>
</pre></div><div class='alt'><pre><a id='n28' href='#n28'>28</a>
</pre></div><div class='alt'><pre><a id='n29' href='#n29'>29</a>
</pre></div><div class='alt'><pre><a id='n30' href='#n30'>30</a>
</pre></div><div class='alt'><pre><a id='n31' href='#n31'>31</a>
</pre></div></td>
<td class='lines'><div><div><div class='alt'><pre>


              </pre></div><div class='alt'><pre>
             </pre></div><div class='alt'><pre>
             </pre></div><div class='alt'><pre>
                 </pre></div><div class='alt'><pre>
                 </pre></div><div class='alt'><pre>


                                                  </pre></div><div class='alt'><pre>

 </pre></div><div class='alt'><pre>
                                                                       </pre></div><div class='alt'><pre>
                                                                          </pre></div><div class='alt'><pre>

                                   </pre></div><div class='alt'><pre>

                               </pre></div><div class='alt'><pre>
                                         </pre></div><div class='alt'><pre>




                                                                </pre></div><div class='alt'><pre>


                                                                    </pre></div><div class='alt'><pre>
         </pre></div><div class='alt'><pre>
                                </pre></div><div class='alt'><pre>
                          </pre></div><div class='alt'><pre>
 </pre></div></div><pre><code>