1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #2094 from OlegHahm/fix_bitarithm

core: Fix bitarithm and unittests
This commit is contained in:
Oleg Hahm 2014-11-27 13:02:44 +01:00
commit 565d70cab3
2 changed files with 36 additions and 24 deletions

View File

@ -15,36 +15,47 @@
* *
* @author Kaspar Schleiser <kaspar@schleiser.de> * @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Martin Lenders <mlenders@inf.fu-berlin.de> * @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author René Kijewski <rene.kijewski@fu-berlin.de>
* *
* @} * @}
*/ */
#include <stdio.h> #include <stdio.h>
#include "bitarithm.h"
unsigned bitarithm_msb(unsigned v) unsigned bitarithm_msb(unsigned v)
{ {
if ((signed) v >= 0) { register unsigned r; // result of log2(v) will go here
v &= -v;
return bitarithm_lsb(v);
}
else {
return sizeof (v) * 8 - 1;
}
}
unsigned bitarithm_lsb(unsigned v) #if ARCH_32_BIT
{ register unsigned shift;
unsigned r = 0;
while ((v & 1) == 0) { r = (v > 0xFFFF) << 4; v >>= r;
v >>= 1; 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++; r++;
} }
#endif
return r; return r;
} }
/*---------------------------------------------------------------------------*/
unsigned bitarithm_lsb(register unsigned v)
{
register unsigned r = 0;
while ((v & 0x01) == 0) {
v >>= 1;
r++;
};
return r;
}
/*---------------------------------------------------------------------------*/
unsigned bitarithm_bits_set(unsigned v) unsigned bitarithm_bits_set(unsigned v)
{ {
unsigned c; // c accumulates the total bits set in v unsigned c; // c accumulates the total bits set in v

View File

@ -7,6 +7,7 @@
*/ */
#include <limits.h> #include <limits.h>
#include <stdint.h>
#include "embUnit/embUnit.h" #include "embUnit/embUnit.h"
@ -153,14 +154,14 @@ static void test_bitarithm_msb_limit(void)
static void test_bitarithm_msb_random(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 ;-) */ 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) { for (unsigned i = 1; i < UINT16_MAX; i++) {
TEST_ASSERT_EQUAL_INT(shift, bitarithm_msb(1 << shift)); TEST_ASSERT_EQUAL_INT(((sizeof(unsigned) * 8) - __builtin_clz(i) - 1), bitarithm_msb(i));
} }
} }
@ -177,14 +178,14 @@ static void test_bitarithm_lsb_limit(void)
static void test_bitarithm_lsb_random(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 ;-) */ dice roll ;-) */
} }
static void test_bitarithm_lsb_all(void) static void test_bitarithm_lsb_all(void)
{ {
for (unsigned shift = 0; shift < sizeof(unsigned) * 8 - 1; ++shift) { for (unsigned i = 1; i < UINT16_MAX; i++) {
TEST_ASSERT_EQUAL_INT(shift, bitarithm_lsb(1u << shift)); TEST_ASSERT_EQUAL_INT(__builtin_ctz(i), bitarithm_lsb(i));
} }
} }
@ -232,7 +233,7 @@ Test *tests_core_bitarithm_tests(void)
new_TestFixture(test_bitarithm_msb_one), new_TestFixture(test_bitarithm_msb_one),
new_TestFixture(test_bitarithm_msb_limit), new_TestFixture(test_bitarithm_msb_limit),
new_TestFixture(test_bitarithm_msb_random), 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_one),
new_TestFixture(test_bitarithm_lsb_limit), new_TestFixture(test_bitarithm_lsb_limit),