C快速计算4的下一个倍数?

时间:2010-01-07 17:18:47

标签: c bit-manipulation

将未签名的int简化为4的倍数的快速方法是什么?

4的倍数有两个最低有效位0,对吗?所以我可以将它们屏蔽掉,然后执行switch语句,在给定的uint中添加1,2或3。

这不是一个非常优雅的解决方案..

还有算术综述:

 myint == 0 ? 0 : ((myint+3)/4)*4

可能有更好的方法包括一些位操作?

7 个答案:

答案 0 :(得分:41)

(myint + 3) & ~0x03

3的加法使得4的下一个倍数变为4的前一个倍数,这是由模运算产生的,可以通过屏蔽来实现,因为除数是2的幂。

答案 1 :(得分:15)

我假设您要实现的是输入数字的对齐,即如果原始数字已经是4的倍数,则不需要更改。但是,您的问题并不清楚。即使原始数字已经是倍数,也许你想要下一个倍数?请澄清一下。

为了在任意边界i上对齐任意非负数n,您只需要做

i = i / n * n;

但这将使其与负无穷大相对应。为了使其与正无穷大对齐,请在执行对齐之前添加n - 1

i = (i + n - 1) / n * n;

这已经足够用于所有意图和目的。在你的情况下,它将是

i = (i + 3) / 4 * 4;

但是,如果您希望从中挤出几个CPU时钟,您可能会使用这样一个事实:i / 4 * 4可以替换为一个有点笨拙的i & ~0x3,给你

i = (i + 3) & ~0x3;
如果现代编译器能够自己找出后者,那就不会让我感到惊讶。

答案 2 :(得分:4)

如果通过“4的下一个倍数”表示4的最小倍数大于未签名的int值myint,那么这将起作用:

(myint | 0x03) + 1;

答案 3 :(得分:1)

(myint + 4)& 0xFFFC

答案 4 :(得分:0)

如果您希望4的下一个倍数严格大于myint,则此解决方案将执行此操作(类似于之前的帖子):

(myint + 4) & ~3u

如果您想要舍入到最接近的4的倍数(如果 是4的倍数,则保持myint不变),这应该有效:

(0 == myint & 0x3) ? myint : ((myint + 4) & ~3u);

答案 5 :(得分:0)

这是无分支的,通常是可配置的,易于理解(如果您了解C字节字符串),它可以让您避免考虑myInt的位大小:

myInt += "\x00\x03\x02\x01"[myInt & 0x3];

唯一的缺点是可能的单个内存访问其他地方(静态字符串存储)而不是堆栈。

答案 6 :(得分:-1)

myint =(myint + 4)& 0xffffffc

这假设通过“下一个4的倍数”,你总是向上移动;即5 - > 8和4 - > 8。