diff --git a/inc/ti/fn/fnbitcount.h b/inc/ti/fn/fnbitcount.h index 7a114135..0eb0e4de 100644 --- a/inc/ti/fn/fnbitcount.h +++ b/inc/ti/fn/fnbitcount.h @@ -16,11 +16,10 @@ static int do__f_bit_count(ti_query_t * query, cleri_node_t * nd, ex_t * e) v = i < 0 ? 0-(uint64_t)i : (uint64_t)i; // from http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel - c = v - ((v >> 1) & 0x55555555); - c = ((c >> 2) & 0x33333333) + (c & 0x33333333); - c = ((c >> 4) + c) & 0x0F0F0F0F; - c = ((c >> 8) + c) & 0x00FF00FF; - c = ((c >> 16) + c) & 0x0000FFFF; + v = v - ((v >> 1) & (uint64_t)~(uint64_t)0/3); + v = (v & (uint64_t)~(uint64_t)0/15*3) + ((v >> 2) & (uint64_t)~(uint64_t)0/15*3); + v = (v + (v >> 4)) & (uint64_t)~(uint64_t)0/255*15; + c = (uint64_t)(v * ((uint64_t)~(uint64_t)0/255)) >> (sizeof(uint64_t) - 1) * CHAR_BIT; ti_val_unsafe_drop(query->rval); diff --git a/itest/test_collection_functions.py b/itest/test_collection_functions.py index 188434e1..998e241d 100755 --- a/itest/test_collection_functions.py +++ b/itest/test_collection_functions.py @@ -5957,9 +5957,13 @@ async def test_bit_count(self, client): res = await client.query("""//ti range(-1000, 1000).map(|i| i.bit_count()); """) - self.assertEqual(res, [i.bit_count() for i in range(-1000, 1000)]) + res = await client.query("""//ti + ((5 << 60) + 5).bit_count(); + """) + self.assertEqual(res, 4) + if __name__ == '__main__': run_test(TestCollectionFunctions())