summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2014-04-06 20:12:46 +0200
committerAndreas Rumpf <rumpf_a@web.de>2014-04-06 20:12:46 +0200
commitb988f75a3582c973f8f7ddebf15f76a506682315 (patch)
tree216ac78183ce8f55a4d8c1233d50c462f175b7aa
parent5d6053173a0db2b4d0dd1c334c41075fe8d9850e (diff)
parent8095fbf982151066e6bfa1e944d17fcb9b5905ea (diff)
downloadNim-b988f75a3582c973f8f7ddebf15f76a506682315.tar.gz
Merge pull request #1071 from ReneSac/devel
Zero is not a power of two. Fixes #1047
-rw-r--r--lib/nimbase.h2
-rw-r--r--lib/pure/math.nim26
2 files changed, 15 insertions, 13 deletions
diff --git a/lib/nimbase.h b/lib/nimbase.h
index b16b27b2c..cfd33dca1 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -376,7 +376,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
 #  define GC_GUARD
 #endif
 
-/* Test to see if nimrod and the C compiler agrees on the size of a pointer.
+/* Test to see if nimrod and the C compiler agree on the size of a pointer.
    On disagreement, your C compiler will say something like: 
    "error: 'assert_numbits' declared as an array with a negative size" */
 typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 94570fc68..d258e9a7c 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -75,28 +75,30 @@ proc binom*(n, k: int): int {.noSideEffect.} =
     result = (result * (n + 1 - i)) div i
     
 proc fac*(n: int): int {.noSideEffect.} = 
-  ## computes the faculty function
+  ## computes the faculty/factorial function.
   result = 1
   for i in countup(2, n):
     result = result * i
 
 proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
-  ## returns true, if x is a power of two, false otherwise.
-  ## Negative numbers are not a power of two.
-  return (x and -x) == x
-
-proc nextPowerOfTwo*(x: int): int =
-  ## returns the nearest power of two, so that
-  ## result**2 >= x > (result-1)**2.
-  result = x - 1
+  ## 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)
+
+proc nextPowerOfTwo*(x: int): int {.noSideEffect.} =
+  ## returns `x` rounded up to the nearest power of two.
+  ## Zero and negative numbers get rounded up to 1.
+  result = x - 1 
   when defined(cpu64):
     result = result or (result shr 32)
-  result = result or (result shr 16)
-  result = result or (result shr 8)
+  when sizeof(int) > 16:
+    result = result or (result shr 16)
+  when sizeof(int) > 8:
+    result = result or (result shr 8)
   result = result or (result shr 4)
   result = result or (result shr 2)
   result = result or (result shr 1)
-  inc(result)
+  result += 1 + ord(x<=0)
 
 proc countBits32*(n: int32): int {.noSideEffect.} =
   ## counts the set bits in `n`.