diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2014-04-06 20:12:46 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2014-04-06 20:12:46 +0200 |
commit | b988f75a3582c973f8f7ddebf15f76a506682315 (patch) | |
tree | 216ac78183ce8f55a4d8c1233d50c462f175b7aa | |
parent | 5d6053173a0db2b4d0dd1c334c41075fe8d9850e (diff) | |
parent | 8095fbf982151066e6bfa1e944d17fcb9b5905ea (diff) | |
download | Nim-b988f75a3582c973f8f7ddebf15f76a506682315.tar.gz |
Merge pull request #1071 from ReneSac/devel
Zero is not a power of two. Fixes #1047
-rw-r--r-- | lib/nimbase.h | 2 | ||||
-rw-r--r-- | lib/pure/math.nim | 26 |
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`. |