简体   繁体   English

位运算,用于返回次高的2

[英]Bit operations for returning the next-highest power of 2

I want to create a function that returns the next multiple of 2^p. 我想创建一个返回2 ^ p下一个倍数的函数。

Here's an attempt, but not sure if it works...: 这是一种尝试,但不确定是否可行...:

#define P 20
#define ALIGN_FORWARD(x, alignment) ((((int)x) + ((alignment)-1)) & (~((alignment)-1)))

int round_up(int x) 
{
  return ALIGN_FORWARD(x, P);
}

This snippet first fills up all bits below the highest set bit. 该代码段首先填充最高位以下的所有位。 After v |= v >> 1 the first two bits can be copied and so on. v |= v >> 1 ,可以复制前两位,依此类推。 Finally the value is incremented by one. 最后,该值增加一。

uint32_t v = ...;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v += 1;

The unsigned part of uint32_t is important, because otherwise the result would be always 0 , because the sign bit gets extended by the shift operation. uint32_tunsigned部分很重要,因为否则结果将始终为0 ,因为移位操作会扩展符号位。 If the value is a uint64_t , then you have to add a further shift, if it is a uint16_t , then you have to remove a shift. 如果值是uint64_t ,则必须添加一个进一步的移位,如果值是uint16_t ,则必须删除一个移位。

For an input of 8 the result would be 16. You need to test if the input is a power of two if you don't like that. 对于输入8,结果将为16。如果您不喜欢输入,则需要测试输入是否为2的幂。 Knowing that the binary representation of a power of two is one character shorter when you decrement it (8=0b1000, 7=0b111), you can use this guard: 知道将2的幂减少后的二进制表示形式要短一个字符(8 = 0b1000,7 = 0b111),因此可以使用以下防护:

if ((v & (v - 1)) > 0) {
    …
}

(Reproduced from memory. Original from https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 , which contains many more interesting tricks.) (从内存中复制。原始内容来自https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 ,其中包含更多有趣的技巧。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM