C 位破解-四舍五入到8的倍数

C 位破解-四舍五入到8的倍数,c,bit-manipulation,C,Bit Manipulation,谁能解释一下这是如何工作的(asz+7)和~7;它将asz四舍五入到下一个更高的倍数8 很容易看出~7产生11111000(8位表示),因此关闭最后3位,因此产生的任何数字都是8的倍数 我的问题是,在屏蔽[edit]之前将asz添加到7如何产生下一个更高的[end edit]倍数8?我试着把它写在纸上 比如: 1 + 7 = 8 = 1|000 (& ~7) -> 1000 2 + 7 = 9 = 1|001 (& ~7) -> 1000 3 + 7 = 10 =

谁能解释一下这是如何工作的(asz+7)和~7;它将asz四舍五入到下一个更高的倍数8

很容易看出~7产生11111000(8位表示),因此关闭最后3位,因此产生的任何数字都是8的倍数

我的问题是,在屏蔽[edit]之前将asz添加到7如何产生下一个更高的[end edit]倍数8?我试着把它写在纸上

比如:

1 + 7 = 8  = 1|000 (& ~7) -> 1000
2 + 7 = 9  = 1|001 (& ~7) -> 1000
3 + 7 = 10 = 1|010 (& ~7) -> 1000
4 + 7 = 11 = 1|011 (& ~7) -> 1000
5 + 7 = 12 = 1|100 (& ~7) -> 1000
6 + 7 = 13 = 1|101 (& ~7) -> 1000
7 + 7 = 14 = 1|110 (& ~7) -> 1000
8 + 7 = 15 = 1|111 (& ~7) -> 1000
很明显,一种被利用的模式正在出现。有人能帮我解决吗

谢谢大家的回答。这有助于证实我的想法。我继续写上面的模式,当我跨过10时,我可以清楚地看到,如果我可以这样说的话,nos被提升到下一个“8块”


再次感谢。

好吧,面具本身会产生8的精确倍数。将7添加到asz可确保获得下一个更高的倍数。

实际上是将7添加到数字并向下舍入


这具有期望的效果,即向上舍入到8的下一个倍数。(将+8而不是+7相加将使值从8增加到16。)

如果您尝试向下取整,则不需要进行加法。只需执行掩蔽步骤,就可以清除底部的位,然后四舍五入到下一个较低的倍数

如果你想进行四舍五入,首先你必须加上足够的数字,以“通过”下一个8的倍数。然后,相同的掩蔽步骤将返回到8的倍数。你选择7的原因是,它是唯一一个保证“足够大”的数字,如果你的原始数字已经是8的倍数,它可以让你从任何一个数字上升到下一个8的倍数,而不会再上升一个额外的倍数

一般来说,将四舍五入为二的幂:

unsigned int roundTo(unsigned int value, unsigned int roundTo)
{
    return (value + (roundTo - 1)) & ~(roundTo - 1);
}

+7并不是产生一个精确的8的倍数,而是确保你得到下一个最高的8的倍数


编辑:以16秒和几个质量订单击败。哦,好吧,回到潜伏状态。

嗯,你刚才回答了你自己的问题???通过添加7,您可以保证结果将等于或高于8的下一个倍数。然后,截断会得到该倍数。

如果没有+7,它将是8的最大倍数,小于或等于原始数字

添加7不会产生8的倍数。8的倍数由~7的和运算产生~7是7的补码,它是0xffff fff8(除非使用整数中有多少位)。这将截断或向下舍入


在这样做之前添加7可以确保不返回低于asz的值。您已经了解了它的工作原理。

使用
(n/m)*m可以将整数n舍入到任意整数m。
只有当舍入为2的幂时,
和~
位才起作用。通常,您需要
返回((value+roundTo-1)/roundTo)*roundTo取而代之。@GregRogers,你知道除法指令有多贵吗?顺便说一句,如果你想四舍五入到整数的倍数不是基数的倍数,这个技巧就行不通了。简短版本:您不能将8和舍入相加为9,但可以将15和舍入相加为16。@Joost如果您是8的偶数倍,则向下舍入将使您达到下一个8的倍数。那是行不通的。是的,我不确定我(这么多年前)在想什么。我将删除我的评论。