summary refs log tree commit diff stats
path: root/lib/pure/math.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/math.nim')
-rw-r--r--lib/pure/math.nim74
1 files changed, 58 insertions, 16 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index a9e9010f6..494dfc4c8 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -161,6 +161,8 @@ proc randomize*(seed: int) {.benign.}
 when not defined(JS):
   proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
     ## computes the square root of `x`.
+  proc cbrt*(x: float): float {.importc: "cbrt", header: "<math.h>".}
+    ## computes the cubic root of `x`
   
   proc ln*(x: float): float {.importc: "log", header: "<math.h>".}
     ## computes ln(x).
@@ -200,30 +202,64 @@ when not defined(JS):
   proc tanh*(x: float): float {.importc: "tanh", header: "<math.h>".}
   proc pow*(x, y: float): float {.importc: "pow", header: "<math.h>".}
     ## computes x to power raised of y.
+  
+  proc erf*(x: float): float {.importc: "erf", header: "<math.h>".}
+    ## The error function
+  proc erfc*(x: float): float {.importc: "erfc", header: "<math.h>".}
+    ## The complementary error function
+  
+  proc lgamma*(x: float): float {.importc: "lgamma", header: "<math.h>".}
+    ## Natural log of the gamma function
+  proc tgamma*(x: float): float {.importc: "tgamma", header: "<math.h>".}
+    ## The gamma function
     
   # C procs:
-  proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>".}
-  proc rand(): cint {.importc: "rand", header: "<stdlib.h>".}
+  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: "<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
-  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
-      const rand_max = 32767
-      result = (float(rand()) / float(rand_max)) * max
-  proc randomize() =
-    randomize(cast[int](epochTime()))
-
-  proc randomize(seed: int) =
-    srand(cint(seed))
-    when declared(srand48): srand48(seed)
+  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
+      when declared(srand48): srand48(seed)
+    
   proc random(max: int): int =
     result = int(rand()) mod max
 
@@ -387,3 +423,9 @@ when isMainModule and not defined(JS):
   # Check for no side effect annotation
   proc mySqrt(num: float): float {.noSideEffect.} =
     return sqrt(num)
+  
+  # check gamma function
+  assert(tgamma(5.0) == 24.0) # 4!
+  assert(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
+  assert(erf(6.0) > erf(5.0))
+  assert(erfc(6.0) < erfc(5.0))