mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
Merge pull request #18879 from benpicco/bf_popcnt
sys/bitfield: add bf_popcnt()
This commit is contained in:
commit
bec46c55bd
@ -21,6 +21,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "bitfield.h"
|
||||
#include "bitarithm.h"
|
||||
#include "irq.h"
|
||||
|
||||
static inline unsigned _skip_bytes(const uint8_t field[], unsigned nbytes, uint8_t byte)
|
||||
@ -92,3 +93,21 @@ void bf_set_all(uint8_t field[], size_t size)
|
||||
field[bytes] = ~((1U << (8 - bits)) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned bf_popcnt(const uint8_t field[], size_t size)
|
||||
{
|
||||
unsigned bytes = size >> 3;
|
||||
unsigned bits = size & 0x7;
|
||||
unsigned mask = ~((1U << (8 - bits)) - 1);
|
||||
|
||||
unsigned count = 0;
|
||||
for (unsigned i = 0; i < bytes; ++i) {
|
||||
count += bitarithm_bits_set(field[i]);
|
||||
}
|
||||
|
||||
if (bits) {
|
||||
count += bitarithm_bits_set(field[bytes] & mask);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -219,6 +219,16 @@ int bf_find_first_unset(const uint8_t field[], size_t size);
|
||||
*/
|
||||
void bf_set_all(uint8_t field[], size_t size);
|
||||
|
||||
/**
|
||||
* @brief Count set bits in the bitfield
|
||||
*
|
||||
* @param[in] field The bitfield
|
||||
* @param[in] size The size of the bitfield
|
||||
*
|
||||
* @return number of '1' bits in the bitfield
|
||||
*/
|
||||
unsigned bf_popcnt(const uint8_t field[], size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -299,6 +299,27 @@ static void test_bf_set_all(void)
|
||||
TEST_ASSERT_EQUAL_INT(0, field[4]);
|
||||
}
|
||||
|
||||
static void test_bf_popcnt(void)
|
||||
{
|
||||
uint8_t field[5];
|
||||
|
||||
memset(field, 0xff, sizeof(field));
|
||||
bf_set_all(field, 5);
|
||||
TEST_ASSERT_EQUAL_INT(5, bf_popcnt(field, 5));
|
||||
|
||||
field[0] = 0x1;
|
||||
field[1] = 0x80;
|
||||
TEST_ASSERT_EQUAL_INT(2, bf_popcnt(field, 9));
|
||||
|
||||
field[0] = 0x0;
|
||||
field[1] = 0x0;
|
||||
TEST_ASSERT_EQUAL_INT(0, bf_popcnt(field, 16));
|
||||
|
||||
field[0] = 0xff;
|
||||
field[1] = 0xff;
|
||||
TEST_ASSERT_EQUAL_INT(16, bf_popcnt(field, 16));
|
||||
}
|
||||
|
||||
Test *tests_bitfield_tests(void) {
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_bf_set),
|
||||
@ -313,6 +334,7 @@ Test *tests_bitfield_tests(void) {
|
||||
new_TestFixture(test_bf_find_first_set),
|
||||
new_TestFixture(test_bf_find_first_unset),
|
||||
new_TestFixture(test_bf_set_all),
|
||||
new_TestFixture(test_bf_popcnt),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(bitfield_tests, NULL, NULL, fixtures);
|
||||
|
Loading…
Reference in New Issue
Block a user