From a4559ab17e281b4fbbdb182fb8ba4e3d8a9c311c Mon Sep 17 00:00:00 2001 From: ReneSac Date: Sun, 6 Apr 2014 14:18:16 -0300 Subject: Zero is not a power of two. Fix #1047 Also, fixed some docstrings and added {.noSideEffect.} pragma to nextPowerOfTwo(). --- lib/pure/math.nim | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 94570fc68..8934b54ff 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`. -- cgit 1.4.1-2-gfad0 From 83661492e72cba09078ed0a846789228543c29a9 Mon Sep 17 00:00:00 2001 From: ReneSac Date: Sun, 6 Apr 2014 14:20:51 -0300 Subject: Fix typo in previous commit. --- lib/nimbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') 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]; -- cgit 1.4.1-2-gfad0 From 8095fbf982151066e6bfa1e944d17fcb9b5905ea Mon Sep 17 00:00:00 2001 From: ReneSac Date: Sun, 6 Apr 2014 15:07:20 -0300 Subject: Removed trailing ';'. --- lib/pure/math.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 8934b54ff..d258e9a7c 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -83,7 +83,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. -- cgit 1.4.1-2-gfad0