将未签名的int
简化为4
的倍数的快速方法是什么?
4的倍数有两个最低有效位0,对吗?所以我可以将它们屏蔽掉,然后执行switch语句,在给定的uint
中添加1,2或3。
这不是一个非常优雅的解决方案..
还有算术综述:
myint == 0 ? 0 : ((myint+3)/4)*4
可能有更好的方法包括一些位操作?
答案 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。