【问题标题】:Determine length in bytes of content of a variable确定变量内容的字节长度
【发布时间】:2018-01-13 16:33:46
【问题描述】:

我想根据其内容自动确定字段 (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 可以是变量。

【问题讨论】:

  • 非常有趣!我也会试试这个!谢谢
  • 我对这个问题感到困惑。这不是sizeof 的用途吗?
  • sizeof 将返回变量的大小而不是它的内容
  • @Amourk - 该循环要么什么都不做,要么永远循环。
  • @Yunnosch:我认为 OP 想要值的字节数。

标签: c


【解决方案1】:

您可以使用类似于二分搜索的方法来执行此操作:首先比较 65536,然后比较 256 或 16777216,具体取决于第一次比较的结果。这样你总是在两次比较中完成,而你的代码有时需要三个:

uint8 len = (addr < 65536)
    ? ((addr < 256)      ? 1 : 2)
    : ((addr < 16777216) ? 3 : 4);

【讨论】:

  • 不能玩弄?
  • 相反,这段代码总是需要两次比较,而原始代码有时只需要一次。如果输入均匀分布在整个可能值范围内,您可以通过首先检查最大的来平均 1 位比较。如果输入偏向小数字,则原始数据可能会更好。这些都不重要——使用此函数的应用程序的性能不太可能受到明显影响。
  • @JonathanLeffler:一些 OP 的测试需要 3 个比较——在均匀分布的情况下,平均值仍然是 2 :)
  • 同意,原始代码有时需要三个比较。但是,如果数字均匀分布在整个 32 位无符号数字范围内,则每 256 个中的 255 个将有 4 个字节的数据;其余 256 个中的 255 个将有 3 个字节的数据(65,536 个中只有 1 个不会有 3 或 4 个字节的数据);其余的; 256 个中有 255 个将有 2 个字节的数据; 16,777,216 中只有 1 个只有 1 个字节的数据。但数字在整个范围内均匀分布的可能性微乎其微。
【解决方案2】:

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

【讨论】:

  • 我使用的是 Xtensa 106Micro 内核,不是 ARM,但我会尝试。也谢谢你。
【解决方案3】:

获取最高位的位置——唯一对您的问题重要的位置(来自https://stackoverflow.com/a/14085901)。除以 8 得到字节数。

addr = 0x20424;
printf ("%d\n", (fls(addr)+7)>>3);

addr == 0 时返回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? 以获取更多找到最高位集的建议。

【讨论】:

    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2010-10-23
    • 1970-01-01
    相关资源
    最近更新 更多