有人可以帮忙解释这个C one liner的作用吗?

[英]Could someone help explain what this C one liner does?


I can usually figure out most C code but this one is over my head.

我通常可以找出大多数C代码,但这个代码是我的头脑。

#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))

an example usage would be something like:

一个示例用法是这样的:

int x = 57;
kroundup32(x);
//x is now 64

A few other examples are:

其他一些例子是:

1 to 1
2 to 2
7 to 8
31 to 32
60 to 64
3000 to 4096

1至1 2至2 7至8 31至32 60至64 3000至4096

I know it's rounding an integer to it's nearest power of 2, but that's about as far as my knowledge goes.

我知道它将整数四舍五入到它最近的2的幂,但就我的知识而言,这就差不多了。

Any explanations would be greatly appreciated.

任何解释将不胜感激。

Thanks

谢谢

3 个解决方案

#1


20  

(--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
  1. Decrease x by 1
  2. 将x减少1
  3. OR x with (x / 2).
  4. 或x与(x / 2)。
  5. OR x with (x / 4).
  6. 或x与(x / 4)。
  7. OR x with (x / 16).
  8. 或x与(x / 16)。
  9. OR x with (x / 256).
  10. 或x与(x / 256)。
  11. OR x with (x / 65536).
  12. 或x与(x / 65536)。
  13. Increase x by 1.
  14. 将x增加1。

For a 32-bit unsigned integer, this should move a value up to the closest power of 2 that is equal or greater. The OR sections set all the lower bits below the highest bit, so it ends up as a power of 2 minus one, then you add one back to it. It looks like it's somewhat optimized and therefore not very readable; doing it by bitwise operations and bit shifting alone, and as a macro (so no function call overhead).

对于32位无符号整数,这应该将值移动到等于或大于2的最接近幂。 OR部分将所有低位设置为最高位以下,因此它最终为2减去1的幂,然后向其添加一个。看起来它有点优化,因此不太可读;通过按位运算和单独的位移,以及作为宏(因此没有函数调用开销)来完成它。

#2


6  

The bitwise or and shift operations essentially set every bit between the highest set bit and bit zero. This will produce a number of the form 2^n - 1. The final increment adds one to get a number of the form 2^n. The initial decrement ensures that you don't round numbers which are already powers of two up to the next power, so that e.g. 2048 doesn't become 4096.

按位或移位操作基本上设置最高设置位和位0之间的每个位。这将产生一些形式2 ^ n - 1.最后的增量增加一个以获得形式2 ^ n的数字。初始减量确保您不会将已经为2的幂的数字舍入到下一个幂,以便例如2048年不会成为4096。

#3


6  

At my machine kroundup32 gives 6.000m rounds/sec
And next function gives 7.693m rounds/sec

在我的机器上kroundup32给出6.000m回合/秒而下一个功能给出7.693m回合/秒

inline int scan_msb(int x)
{
#if defined(__i386__) || defined(__x86_64__)
    int y;
    __asm__("bsr %1, %0"
            : "=r" (y)
            : "r" (x)
            : "flags"); /* ZF */
    return y;
#else
#error "Implement me for your platform"
#endif
}

inline int roundup32(int x)
{
    if (x == 0) return x;
    else {
        const int bit = scan_msb(x);
        const int mask = ~((~0) << bit);
        if (x & mask) return (1 << (bit+1));
        else return (1 << bit);
    }
}

So @thomasrutter I woudn't say that it is "highly optimized".

所以@thomasrutter我不是说它是“高度优化的”。

And appropriate (only meaningful part) assembly (for GCC 4.4.4):

适当的(仅有意义的部分)装配(适用于GCC 4.4.4):

kroundup32:
    subl    $1, %edi
    movl    %edi, %eax
    sarl    %eax
    orl %edi, %eax
    movl    %eax, %edx
    sarl    $2, %edx
    orl %eax, %edx
    movl    %edx, %eax
    sarl    $4, %eax
    orl %edx, %eax
    movl    %eax, %edx
    sarl    $8, %edx
    orl %eax, %edx
    movl    %edx, %eax
    sarl    $16, %eax
    orl %edx, %eax
    addl    $1, %eax
    ret

roundup32:
    testl   %edi, %edi
    movl    %edi, %eax
    je  .L6
    movl    $-1, %edx
    bsr %edi, %ecx
    sall    %cl, %edx
    notl    %edx
    testl   %edi, %edx
    jne .L10
    movl    $1, %eax
    sall    %cl, %eax
.L6:
    rep
    ret
.L10:
    addl    $1, %ecx
    movl    $1, %eax
    sall    %cl, %eax
    ret

By some reason I haven't found appropriate implementation of scan_msb (like #define scan_msb(x) if (__builtin_constant_p (x)) ...) within standart headers of GCC (only __TBB_machine_lg/__TBB_Log2).

由于某种原因,我没有找到适当的scan_msb实现(如#define scan_msb(x)if(__ builtin_constant_p(x))...)在GCC的标准头文件中(仅__TBB_machine_lg / __ TBB_Log2)。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2010/08/02/82547738a03e5316351cb89be9802fec.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号