我想基于它的内容自动确定addr
字段(uint32
)的字节长度。编译器是GCC。我用这个:
uint8 len;
if(addr < 256) len = 1;
else if (addr < 65536) len = 2;
else if (addr < 16777216) len = 3;
else len = 4;
有更有效的方法吗?
这是嵌入式设备的SPI功能。我对除宏之外的最快方式感兴趣,因为addr
可以是一个变量。
答案 0 :(得分:4)
您可以使用类似于二分搜索的方法来执行此操作:首先与65536
进行比较,然后与256或16777216进行比较,具体取决于第一次比较的结果。这样你总是可以完成两次比较,而你的代码有时需要三次:
uint8 len = (addr < 65536)
? ((addr < 256) ? 1 : 2)
: ((addr < 16777216) ? 3 : 4);
答案 1 :(得分:1)
gcc有一个__builtin_ctz()
函数,可以像
if (addr == 0)
len = 0;
else
len = (sizeof(int) * 8 - __builtin_ctz(addr) + 7) / 8;
更新
在ARM下,编译为
cmp r0, #0
rbitne r0, r0
clzne r0, r0
rsbne r0, r0, #39
lsrne r0, r0, #3
bx lr
答案 2 :(得分:1)
获取最高位的位置 - 唯一符合您问题的位置(来自https://stackoverflow.com/a/14085901)。除以8得到字节数。
addr = 0x20424;
printf ("%d\n", (fls(addr)+7)>>3);
0
时会返回addr == 0
。
fls
符合POSIX.1-2001,POSIX.1-2008,4.3BSD。如果您当前的系统不包含它,请查看上面的链接或What is the fastest/most efficient way to find the highest set bit (msb) in an integer in C?以获取更多建议,以找到最高位集。