summary refs log tree commit diff stats
path: root/lib/pure/math.nim
diff options
context:
space:
mode:
authorSimon Hafner <hafnersimon@gmail.com>2015-05-13 12:06:05 -0500
committerSimon Hafner <hafnersimon@gmail.com>2015-05-13 12:06:05 -0500
commit9c4a74637db266c3cfcffcfb1e65bae982c6e4bf (patch)
tree495f50a989d7ab696ddb0b7b0e815c572ab27f3c /lib/pure/math.nim
parentc55f884b5c0ebc0b637138a8de446ba1fd05acdf (diff)
parent0b184f2584221543a7dec9c8ae4a700533919e0c (diff)
downloadNim-9c4a74637db266c3cfcffcfb1e65bae982c6e4bf.tar.gz
Merge branch 'devel' into jpoirier-realtimeGCTest
Diffstat (limited to 'lib/pure/math.nim')
-rw-r--r--lib/pure/math.nim30
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index c902af381..cb58ea39b 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -85,7 +85,7 @@ proc fac*(n: int): int {.noSideEffect.} =
 proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
   ## returns true, if `x` is a power of two, false otherwise.
   ## Zero and negative numbers are not a power of two.
-  return (x != 0) and ((x and (x - 1)) == 0)
+  return (x > 0) and ((x and (x - 1)) == 0)
 
 proc nextPowerOfTwo*(x: int): int {.noSideEffect.} =
   ## returns `x` rounded up to the nearest power of two.
@@ -114,18 +114,23 @@ proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
   ## If `x` is empty, 0 is returned.
   for i in items(x): result = result + i
 
-proc mean*(x: openArray[float]): float {.noSideEffect.} = 
-  ## computes the mean of the elements in `x`. 
+template toFloat(f: float): float = f
+
+proc mean*[T](x: openArray[T]): float {.noSideEffect.} =
+  ## computes the mean of the elements in `x`, which are first converted to floats.
   ## If `x` is empty, NaN is returned.
-  result = sum(x) / toFloat(len(x))
+  ## ``toFloat(x: T): float`` must be defined.
+  for i in items(x): result = result + toFloat(i)
+  result = result / toFloat(len(x))
 
-proc variance*(x: openArray[float]): float {.noSideEffect.} = 
+proc variance*[T](x: openArray[T]): float {.noSideEffect.} =
   ## computes the variance of the elements in `x`. 
   ## If `x` is empty, NaN is returned.
+  ## ``toFloat(x: T): float`` must be defined.
   result = 0.0
   var m = mean(x)
-  for i in 0 .. high(x):
-    var diff = x[i] - m
+  for i in items(x):
+    var diff = toFloat(i) - m
     result = result + diff*diff
   result = result / toFloat(len(x))
 
@@ -152,6 +157,7 @@ proc randomize*(seed: int) {.benign.}
   ## Note: Does nothing for the JavaScript target,
   ## as JavaScript does not support this.
 
+{.push noSideEffect.}
 when not defined(JS):
   proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
     ## computes the square root of `x`.
@@ -273,6 +279,8 @@ else:
     var y = exp(2.0*x)
     return (y-1.0)/(y+1.0)
 
+{.pop.}
+
 proc `mod`*(x, y: float): float =
   result = if y == 0.0: x else: x - y * (x/y).floor
 
@@ -369,4 +377,10 @@ when isMainModule and not defined(JS):
   randomize(seed)
   for i in 0..SIZE-1:
     assert buf[i] == random(high(int)), "non deterministic random seeding"
-  echo "random values equal after reseeding"
+
+  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)