o Added bit_array_count_bits().
o Padding after the last significant bit is guaranteed to be 0.
o BIT_ARRAY_FISH_BITS_... is not destructive any longer.
wildmatch regex \
prime primetable random \
time-stamp time-timer time-conf \
- bit-ffs bit-fls \
+ bit-ffs bit-fls bit-count \
url \
mainloop main-block main-rec \
proctitle exitstatus runcmd \
$(o)/ucw/hash-test.test: $(o)/ucw/hash-test
$(o)/ucw/mempool.test: $(o)/ucw/mempool-t $(o)/ucw/mempool-fmt-t $(o)/ucw/mempool-str-t
$(o)/ucw/stkstring.test: $(o)/ucw/stkstring-t
-$(o)/ucw/bitops.test: $(o)/ucw/bit-ffs-t $(o)/ucw/bit-fls-t
+$(o)/ucw/bitops.test: $(o)/ucw/bit-ffs-t $(o)/ucw/bit-fls-t $(o)/ucw/bit-count-t
$(o)/ucw/slists.test: $(o)/ucw/slists-t
$(o)/ucw/kmp-test.test: $(o)/ucw/kmp-test
$(o)/ucw/bbuf.test: $(o)/ucw/bbuf-t
--- /dev/null
+/*
+ * UCW Library -- Counting bits in bitarray
+ *
+ * (c) 2012 Pavel Charvat <pchar@ucw.cz>
+ *
+ * This software may be freely distributed and used according to the terms
+ * of the GNU Lesser General Public License.
+ */
+
+#include <ucw/lib.h>
+#include <ucw/bitops.h>
+#include <ucw/bitarray.h>
+
+uns bit_array_count_bits(bitarray_t a, uns n)
+{
+ uns m = 0;
+ n = BIT_ARRAY_WORDS(n);
+ while (n--)
+ m += bit_count(*a++);
+ return m;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <alloca.h>
+
+int main(void)
+{
+ char buf[1024];
+ bitarray_t a = alloca(BIT_ARRAY_BYTES(sizeof(buf)));
+ while (1)
+ {
+ if (!fgets(buf, sizeof(buf), stdin))
+ return 0;
+ uns n;
+ for (n = 0; buf[n] == '0' || buf[n] == '1'; n++);
+ bit_array_zero(a, n);
+ for (uns i = 0; i < n; i++)
+ if (buf[i] == '1')
+ bit_array_set(a, i);
+ printf("%u\n", bit_array_count_bits(a, n));
+ }
+}
+
+#endif
* UCW Library -- Bit Array Operations
*
* (c) 2003--2006 Martin Mares <mj@ucw.cz>
+ * (c) 2012 Pavel Charvat <pchar@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
#include <string.h>
-typedef u32 *bitarray_t;
+typedef u32 *bitarray_t; // Must be initialized by bit_array_xmalloc(), bit_array_zero() or bit_array_set_all()
+
#define BIT_ARRAY_WORDS(n) (((n)+31)/32)
#define BIT_ARRAY_BYTES(n) (4*BIT_ARRAY_WORDS(n))
#define BIT_ARRAY(name,size) u32 name[BIT_ARRAY_WORDS(size)]
static inline void
bit_array_set_all(bitarray_t a, uns n)
{
- memset(a, 255, BIT_ARRAY_BYTES(n));
+ uns w = n / 32;
+ memset(a, 255, w * 4);
+ uns m = n & 31;
+ if (m)
+ a[w] = (1U << m) - 1;
}
static inline void
return t;
}
-/* Iterate over all set bits, possibly destructively */
+uns bit_array_count_bits(bitarray_t a, uns n);
+
+/* Iterate over all set bits */
#define BIT_ARRAY_FISH_BITS_BEGIN(var,ary,size) \
for (uns var##_hi=0; var##_hi < BIT_ARRAY_WORDS(size); var##_hi++) \
- for (uns var##_lo=0; ary[var##_hi]; var##_lo++) \
- if (ary[var##_hi] & (1 << var##_lo)) \
- { \
- uns var = 32*var##_hi + var##_lo; \
- ary[var##_hi] &= ~(1 << var##_lo); \
+ { \
+ u32 var##_cur = ary[var##_hi]; \
+ for (uns var = 32 * var##_hi; var##_cur; var++, var##_cur >>= 1) \
+ if (var##_cur & 1) \
do
#define BIT_ARRAY_FISH_BITS_END \
while (0); \
- }
+ }
#endif
17
9
27
+
+Run: ../obj/ucw/bit-count-t
+In: 11111111111111111
+ 000000000000
+ 0001010000
+ 1001010101010000010111100011100001110010101010000111000011100000001001010101000101010
+Out: 17
+ 0
+ 2
+ 35