Skip to content

Commit

Permalink
Merge pull request #2094 from OlegHahm/fix_bitarithm
Browse files Browse the repository at this point in the history
core: Fix bitarithm and unittests
  • Loading branch information
OlegHahm committed Nov 27, 2014
2 parents bd74f3a + d34e144 commit 565d70c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 23 deletions.
41 changes: 26 additions & 15 deletions core/bitarithm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,47 @@
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author René Kijewski <rene.kijewski@fu-berlin.de>
*
* @}
*/

#include <stdio.h>

#include "bitarithm.h"

unsigned bitarithm_msb(unsigned v)
{
if ((signed) v >= 0) {
v &= -v;
return bitarithm_lsb(v);
}
else {
return sizeof (v) * 8 - 1;
register unsigned r; // result of log2(v) will go here

#if ARCH_32_BIT
register unsigned shift;

r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
#else
r = 0;
while (v >>= 1) { // unroll for more speed...
r++;
}
}

unsigned bitarithm_lsb(unsigned v)
#endif

return r;
}
/*---------------------------------------------------------------------------*/
unsigned bitarithm_lsb(register unsigned v)
{
unsigned r = 0;
while ((v & 1) == 0) {
register unsigned r = 0;

while ((v & 0x01) == 0) {
v >>= 1;
r++;
}
};

return r;
}

/*---------------------------------------------------------------------------*/
unsigned bitarithm_bits_set(unsigned v)
{
unsigned c; // c accumulates the total bits set in v
Expand Down
17 changes: 9 additions & 8 deletions tests/unittests/tests-core/tests-core-bitarithm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include <limits.h>
#include <stdint.h>

#include "embUnit/embUnit.h"

Expand Down Expand Up @@ -153,14 +154,14 @@ static void test_bitarithm_msb_limit(void)

static void test_bitarithm_msb_random(void)
{
TEST_ASSERT_EQUAL_INT(2, bitarithm_msb(4)); /* randomized by fair
TEST_ASSERT_EQUAL_INT(4, bitarithm_msb(19)); /* randomized by fair
dice roll ;-) */
}

static void test_bitarithm_msb_all(void)
static void test_bitarithm_msb_16bit(void)
{
for (unsigned shift = 0; shift < sizeof(unsigned) * 8 - 1; ++shift) {
TEST_ASSERT_EQUAL_INT(shift, bitarithm_msb(1 << shift));
for (unsigned i = 1; i < UINT16_MAX; i++) {
TEST_ASSERT_EQUAL_INT(((sizeof(unsigned) * 8) - __builtin_clz(i) - 1), bitarithm_msb(i));
}
}

Expand All @@ -177,14 +178,14 @@ static void test_bitarithm_lsb_limit(void)

static void test_bitarithm_lsb_random(void)
{
TEST_ASSERT_EQUAL_INT(3, bitarithm_lsb(8)); /* randomized by fair
TEST_ASSERT_EQUAL_INT(3, bitarithm_lsb(24)); /* randomized by fair
dice roll ;-) */
}

static void test_bitarithm_lsb_all(void)
{
for (unsigned shift = 0; shift < sizeof(unsigned) * 8 - 1; ++shift) {
TEST_ASSERT_EQUAL_INT(shift, bitarithm_lsb(1u << shift));
for (unsigned i = 1; i < UINT16_MAX; i++) {
TEST_ASSERT_EQUAL_INT(__builtin_ctz(i), bitarithm_lsb(i));
}
}

Expand Down Expand Up @@ -232,7 +233,7 @@ Test *tests_core_bitarithm_tests(void)
new_TestFixture(test_bitarithm_msb_one),
new_TestFixture(test_bitarithm_msb_limit),
new_TestFixture(test_bitarithm_msb_random),
new_TestFixture(test_bitarithm_msb_all),
new_TestFixture(test_bitarithm_msb_16bit),

new_TestFixture(test_bitarithm_lsb_one),
new_TestFixture(test_bitarithm_lsb_limit),
Expand Down

0 comments on commit 565d70c

Please # to comment.