|
@@ -15,7 +15,7 @@
|
|
|
* Returns the number of 1 bits in the indicated word.
|
|
* Returns the number of 1 bits in the indicated word.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-count_bits_in_word(uint16_t x) {
|
|
|
|
|
|
|
+count_bits_in_word(unsigned short x) {
|
|
|
return (int)num_bits_on[x];
|
|
return (int)num_bits_on[x];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -23,9 +23,9 @@ count_bits_in_word(uint16_t x) {
|
|
|
* Returns the number of 1 bits in the indicated word.
|
|
* Returns the number of 1 bits in the indicated word.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-count_bits_in_word(uint32_t x) {
|
|
|
|
|
|
|
+count_bits_in_word(unsigned int x) {
|
|
|
#if defined(__GNUC__) && defined(__POPCNT__)
|
|
#if defined(__GNUC__) && defined(__POPCNT__)
|
|
|
- return __builtin_popcount((unsigned int) x);
|
|
|
|
|
|
|
+ return __builtin_popcount(x);
|
|
|
#else
|
|
#else
|
|
|
return (int)num_bits_on[x & 0xffff] + (int)num_bits_on[(x >> 16) & 0xffff];
|
|
return (int)num_bits_on[x & 0xffff] + (int)num_bits_on[(x >> 16) & 0xffff];
|
|
|
#endif
|
|
#endif
|
|
@@ -35,44 +35,74 @@ count_bits_in_word(uint32_t x) {
|
|
|
* Returns the number of 1 bits in the indicated word.
|
|
* Returns the number of 1 bits in the indicated word.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-count_bits_in_word(uint64_t x) {
|
|
|
|
|
|
|
+count_bits_in_word(unsigned long x) {
|
|
|
#if defined(__GNUC__) && defined(__POPCNT__)
|
|
#if defined(__GNUC__) && defined(__POPCNT__)
|
|
|
- return __builtin_popcountll((unsigned long long) x);
|
|
|
|
|
|
|
+ return __builtin_popcountl(x);
|
|
|
|
|
+#elif defined(_LP64)
|
|
|
|
|
+ return count_bits_in_word((unsigned int)x) + count_bits_in_word((unsigned int)(x >> 32));
|
|
|
#else
|
|
#else
|
|
|
- return count_bits_in_word((uint32_t)x) + count_bits_in_word((uint32_t)(x >> 32));
|
|
|
|
|
|
|
+ return count_bits_in_word((unsigned int)x);
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Returns the number of 1 bits in the indicated word.
|
|
|
|
|
+ */
|
|
|
|
|
+INLINE int
|
|
|
|
|
+count_bits_in_word(unsigned long long x) {
|
|
|
|
|
+#if defined(__GNUC__) && defined(__POPCNT__)
|
|
|
|
|
+ return __builtin_popcountll(x);
|
|
|
|
|
+#else
|
|
|
|
|
+ return count_bits_in_word((unsigned int)x) + count_bits_in_word((unsigned int)(x >> 32));
|
|
|
|
|
+#endif
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Returns a value such that every bit at or below the highest bit in x is 1.
|
|
|
|
|
+ */
|
|
|
|
|
+INLINE unsigned short
|
|
|
|
|
+flood_bits_down(unsigned short x) {
|
|
|
|
|
+ x |= (x >> 1);
|
|
|
|
|
+ x |= (x >> 2);
|
|
|
|
|
+ x |= (x >> 4);
|
|
|
|
|
+ x |= (x >> 8);
|
|
|
|
|
+ return x;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Returns a value such that every bit at or below the highest bit in x is 1.
|
|
* Returns a value such that every bit at or below the highest bit in x is 1.
|
|
|
*/
|
|
*/
|
|
|
-INLINE uint16_t
|
|
|
|
|
-flood_bits_down(uint16_t x) {
|
|
|
|
|
|
|
+INLINE unsigned int
|
|
|
|
|
+flood_bits_down(unsigned int x) {
|
|
|
x |= (x >> 1);
|
|
x |= (x >> 1);
|
|
|
x |= (x >> 2);
|
|
x |= (x >> 2);
|
|
|
x |= (x >> 4);
|
|
x |= (x >> 4);
|
|
|
x |= (x >> 8);
|
|
x |= (x >> 8);
|
|
|
|
|
+ x |= (x >> 16);
|
|
|
return x;
|
|
return x;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Returns a value such that every bit at or below the highest bit in x is 1.
|
|
* Returns a value such that every bit at or below the highest bit in x is 1.
|
|
|
*/
|
|
*/
|
|
|
-INLINE uint32_t
|
|
|
|
|
-flood_bits_down(uint32_t x) {
|
|
|
|
|
|
|
+INLINE unsigned long
|
|
|
|
|
+flood_bits_down(unsigned long x) {
|
|
|
x |= (x >> 1);
|
|
x |= (x >> 1);
|
|
|
x |= (x >> 2);
|
|
x |= (x >> 2);
|
|
|
x |= (x >> 4);
|
|
x |= (x >> 4);
|
|
|
x |= (x >> 8);
|
|
x |= (x >> 8);
|
|
|
x |= (x >> 16);
|
|
x |= (x >> 16);
|
|
|
|
|
+#if defined(_LP64) || defined(__LP64__)
|
|
|
|
|
+ x |= (x >> 32);
|
|
|
|
|
+#endif
|
|
|
return x;
|
|
return x;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Returns a value such that every bit at or below the highest bit in x is 1.
|
|
* Returns a value such that every bit at or below the highest bit in x is 1.
|
|
|
*/
|
|
*/
|
|
|
-INLINE uint64_t
|
|
|
|
|
-flood_bits_down(uint64_t x) {
|
|
|
|
|
|
|
+INLINE unsigned long long
|
|
|
|
|
+flood_bits_down(unsigned long long x) {
|
|
|
x |= (x >> 1);
|
|
x |= (x >> 1);
|
|
|
x |= (x >> 2);
|
|
x |= (x >> 2);
|
|
|
x |= (x >> 4);
|
|
x |= (x >> 4);
|
|
@@ -85,8 +115,8 @@ flood_bits_down(uint64_t x) {
|
|
|
/**
|
|
/**
|
|
|
* Returns a value such that every bit at or above the highest bit in x is 1.
|
|
* Returns a value such that every bit at or above the highest bit in x is 1.
|
|
|
*/
|
|
*/
|
|
|
-INLINE uint16_t
|
|
|
|
|
-flood_bits_up(uint16_t x) {
|
|
|
|
|
|
|
+INLINE unsigned short
|
|
|
|
|
+flood_bits_up(unsigned short x) {
|
|
|
x |= (x << 1);
|
|
x |= (x << 1);
|
|
|
x |= (x << 2);
|
|
x |= (x << 2);
|
|
|
x |= (x << 4);
|
|
x |= (x << 4);
|
|
@@ -97,8 +127,8 @@ flood_bits_up(uint16_t x) {
|
|
|
/**
|
|
/**
|
|
|
* Returns a value such that every bit at or above the highest bit in x is 1.
|
|
* Returns a value such that every bit at or above the highest bit in x is 1.
|
|
|
*/
|
|
*/
|
|
|
-INLINE uint32_t
|
|
|
|
|
-flood_bits_up(uint32_t x) {
|
|
|
|
|
|
|
+INLINE unsigned int
|
|
|
|
|
+flood_bits_up(unsigned int x) {
|
|
|
x |= (x << 1);
|
|
x |= (x << 1);
|
|
|
x |= (x << 2);
|
|
x |= (x << 2);
|
|
|
x |= (x << 4);
|
|
x |= (x << 4);
|
|
@@ -110,8 +140,24 @@ flood_bits_up(uint32_t x) {
|
|
|
/**
|
|
/**
|
|
|
* Returns a value such that every bit at or above the highest bit in x is 1.
|
|
* Returns a value such that every bit at or above the highest bit in x is 1.
|
|
|
*/
|
|
*/
|
|
|
-INLINE uint64_t
|
|
|
|
|
-flood_bits_up(uint64_t x) {
|
|
|
|
|
|
|
+INLINE unsigned long
|
|
|
|
|
+flood_bits_up(unsigned long x) {
|
|
|
|
|
+ x |= (x << 1);
|
|
|
|
|
+ x |= (x << 2);
|
|
|
|
|
+ x |= (x << 4);
|
|
|
|
|
+ x |= (x << 8);
|
|
|
|
|
+ x |= (x << 16);
|
|
|
|
|
+#if defined(_LP64) || defined(__LP64__)
|
|
|
|
|
+ x |= (x << 32);
|
|
|
|
|
+#endif
|
|
|
|
|
+ return x;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Returns a value such that every bit at or above the highest bit in x is 1.
|
|
|
|
|
+ */
|
|
|
|
|
+INLINE unsigned long long
|
|
|
|
|
+flood_bits_up(unsigned long long x) {
|
|
|
x |= (x << 1);
|
|
x |= (x << 1);
|
|
|
x |= (x << 2);
|
|
x |= (x << 2);
|
|
|
x |= (x << 4);
|
|
x |= (x << 4);
|
|
@@ -126,7 +172,7 @@ flood_bits_up(uint64_t x) {
|
|
|
* no 1 bits.
|
|
* no 1 bits.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_lowest_on_bit(uint16_t x) {
|
|
|
|
|
|
|
+get_lowest_on_bit(unsigned short x) {
|
|
|
#if defined(_MSC_VER)
|
|
#if defined(_MSC_VER)
|
|
|
unsigned long result;
|
|
unsigned long result;
|
|
|
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
@@ -137,7 +183,7 @@ get_lowest_on_bit(uint16_t x) {
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- uint16_t w = (x & (~x + 1));
|
|
|
|
|
|
|
+ unsigned short w = (x & (~x + 1));
|
|
|
return (int)num_bits_on[w - 1];
|
|
return (int)num_bits_on[w - 1];
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
@@ -147,7 +193,7 @@ get_lowest_on_bit(uint16_t x) {
|
|
|
* no 1 bits.
|
|
* no 1 bits.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_lowest_on_bit(uint32_t x) {
|
|
|
|
|
|
|
+get_lowest_on_bit(unsigned int x) {
|
|
|
#if defined(_MSC_VER)
|
|
#if defined(_MSC_VER)
|
|
|
unsigned long result;
|
|
unsigned long result;
|
|
|
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
@@ -158,7 +204,28 @@ get_lowest_on_bit(uint32_t x) {
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- uint32_t w = (x & (~x + 1));
|
|
|
|
|
|
|
+ unsigned int w = (x & (~x + 1));
|
|
|
|
|
+ return count_bits_in_word(w - 1);
|
|
|
|
|
+#endif
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Returns the index of the lowest 1 bit in the word. Returns -1 if there are
|
|
|
|
|
+ * no 1 bits.
|
|
|
|
|
+ */
|
|
|
|
|
+INLINE int
|
|
|
|
|
+get_lowest_on_bit(unsigned long x) {
|
|
|
|
|
+#if defined(_MSC_VER) && defined(_M_X64)
|
|
|
|
|
+ unsigned long result;
|
|
|
|
|
+ return (_BitScanForward(&result, x) == 0) ? -1 : result;
|
|
|
|
|
+#elif defined(__GNUC__)
|
|
|
|
|
+ return __builtin_ffsl((long) x) - 1;
|
|
|
|
|
+#else
|
|
|
|
|
+ if (x == 0) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ unsigned long w = (x & (~x + 1));
|
|
|
return count_bits_in_word(w - 1);
|
|
return count_bits_in_word(w - 1);
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
@@ -168,7 +235,7 @@ get_lowest_on_bit(uint32_t x) {
|
|
|
* no 1 bits.
|
|
* no 1 bits.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_lowest_on_bit(uint64_t x) {
|
|
|
|
|
|
|
+get_lowest_on_bit(unsigned long long x) {
|
|
|
#if defined(_MSC_VER) && defined(_M_X64)
|
|
#if defined(_MSC_VER) && defined(_M_X64)
|
|
|
unsigned long result;
|
|
unsigned long result;
|
|
|
return (_BitScanForward64(&result, (unsigned __int64) x) == 0) ? -1 : result;
|
|
return (_BitScanForward64(&result, (unsigned __int64) x) == 0) ? -1 : result;
|
|
@@ -179,7 +246,7 @@ get_lowest_on_bit(uint64_t x) {
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- uint64_t w = (x & (~x + 1));
|
|
|
|
|
|
|
+ unsigned long long w = (x & (~x + 1));
|
|
|
return count_bits_in_word(w - 1);
|
|
return count_bits_in_word(w - 1);
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
@@ -189,14 +256,14 @@ get_lowest_on_bit(uint64_t x) {
|
|
|
* are no 1 bits.
|
|
* are no 1 bits.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_highest_on_bit(uint16_t x) {
|
|
|
|
|
|
|
+get_highest_on_bit(unsigned short x) {
|
|
|
#if defined(_MSC_VER)
|
|
#if defined(_MSC_VER)
|
|
|
unsigned long result;
|
|
unsigned long result;
|
|
|
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
|
#elif defined(__GNUC__)
|
|
#elif defined(__GNUC__)
|
|
|
return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
|
|
return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
|
|
|
#else
|
|
#else
|
|
|
- uint16_t w = flood_bits_down(x);
|
|
|
|
|
|
|
+ unsigned short w = flood_bits_down(x);
|
|
|
return count_bits_in_word(w) - 1;
|
|
return count_bits_in_word(w) - 1;
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
@@ -206,14 +273,31 @@ get_highest_on_bit(uint16_t x) {
|
|
|
* are no 1 bits.
|
|
* are no 1 bits.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_highest_on_bit(uint32_t x) {
|
|
|
|
|
|
|
+get_highest_on_bit(unsigned int x) {
|
|
|
#if defined(_MSC_VER)
|
|
#if defined(_MSC_VER)
|
|
|
unsigned long result;
|
|
unsigned long result;
|
|
|
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
|
#elif defined(__GNUC__)
|
|
#elif defined(__GNUC__)
|
|
|
- return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
|
|
|
|
|
|
|
+ return (x == 0) ? -1 : 31 - __builtin_clz(x);
|
|
|
|
|
+#else
|
|
|
|
|
+ unsigned int w = flood_bits_down(x);
|
|
|
|
|
+ return count_bits_in_word(w) - 1;
|
|
|
|
|
+#endif
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Returns the index of the highest 1 bit in the word. Returns -1 if there
|
|
|
|
|
+ * are no 1 bits.
|
|
|
|
|
+ */
|
|
|
|
|
+INLINE int
|
|
|
|
|
+get_highest_on_bit(unsigned long x) {
|
|
|
|
|
+#if defined(_MSC_VER) && defined(_M_X64)
|
|
|
|
|
+ unsigned long result;
|
|
|
|
|
+ return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
|
|
|
|
+#elif defined(__GNUC__)
|
|
|
|
|
+ return (x == 0) ? -1 : 63 - __builtin_clzl(x);
|
|
|
#else
|
|
#else
|
|
|
- uint32_t w = flood_bits_down(x);
|
|
|
|
|
|
|
+ unsigned long long w = flood_bits_down(x);
|
|
|
return count_bits_in_word(w) - 1;
|
|
return count_bits_in_word(w) - 1;
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
@@ -223,14 +307,14 @@ get_highest_on_bit(uint32_t x) {
|
|
|
* are no 1 bits.
|
|
* are no 1 bits.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_highest_on_bit(uint64_t x) {
|
|
|
|
|
|
|
+get_highest_on_bit(unsigned long long x) {
|
|
|
#if defined(_MSC_VER) && defined(_M_X64)
|
|
#if defined(_MSC_VER) && defined(_M_X64)
|
|
|
unsigned long result;
|
|
unsigned long result;
|
|
|
return (_BitScanReverse64(&result, (unsigned __int64) x) == 0) ? -1 : result;
|
|
return (_BitScanReverse64(&result, (unsigned __int64) x) == 0) ? -1 : result;
|
|
|
#elif defined(__GNUC__)
|
|
#elif defined(__GNUC__)
|
|
|
- return (x == 0) ? -1 : 63 - __builtin_clzll((unsigned long long) x);
|
|
|
|
|
|
|
+ return (x == 0) ? -1 : 63 - __builtin_clzll(x);
|
|
|
#else
|
|
#else
|
|
|
- uint64_t w = flood_bits_down(x);
|
|
|
|
|
|
|
+ unsigned long long w = flood_bits_down(x);
|
|
|
return count_bits_in_word(w) - 1;
|
|
return count_bits_in_word(w) - 1;
|
|
|
#endif
|
|
#endif
|
|
|
}
|
|
}
|
|
@@ -241,7 +325,17 @@ get_highest_on_bit(uint64_t x) {
|
|
|
* Returns the smallest number n such that (1 << n) is larger than x.
|
|
* Returns the smallest number n such that (1 << n) is larger than x.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_next_higher_bit(uint16_t x) {
|
|
|
|
|
|
|
+get_next_higher_bit(unsigned short x) {
|
|
|
|
|
+ return get_highest_on_bit(x) + 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Returns the smallest power of 2 greater than x.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Returns the smallest number n such that (1 << n) is larger than x.
|
|
|
|
|
+ */
|
|
|
|
|
+INLINE int
|
|
|
|
|
+get_next_higher_bit(unsigned int x) {
|
|
|
return get_highest_on_bit(x) + 1;
|
|
return get_highest_on_bit(x) + 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -251,7 +345,7 @@ get_next_higher_bit(uint16_t x) {
|
|
|
* Returns the smallest number n such that (1 << n) is larger than x.
|
|
* Returns the smallest number n such that (1 << n) is larger than x.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_next_higher_bit(uint32_t x) {
|
|
|
|
|
|
|
+get_next_higher_bit(unsigned long x) {
|
|
|
return get_highest_on_bit(x) + 1;
|
|
return get_highest_on_bit(x) + 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -261,6 +355,6 @@ get_next_higher_bit(uint32_t x) {
|
|
|
* Returns the smallest number n such that (1 << n) is larger than x.
|
|
* Returns the smallest number n such that (1 << n) is larger than x.
|
|
|
*/
|
|
*/
|
|
|
INLINE int
|
|
INLINE int
|
|
|
-get_next_higher_bit(uint64_t x) {
|
|
|
|
|
|
|
+get_next_higher_bit(unsigned long long x) {
|
|
|
return get_highest_on_bit(x) + 1;
|
|
return get_highest_on_bit(x) + 1;
|
|
|
}
|
|
}
|