像123以10向下取整是120,想上取整是130。
取数字0x12345678为例子:
它的向下取整为(以0x1000为单位):0x12345678 & 0xfffff000
它的向上取整为(以0x1000为单位):(0x12345678 & 0xfffff000) + 0x1000
那么这样的方法是否有通用性呢?
上面的向下取整有通用性,而向上取整欠缺,试想120向下和向上取整都是120,而如果用上面的方法,向上取整就变成130了,明显是错误的。
那么就必须先判断后3位是否为0了
if((i & 0xfff) != 0) {i = (i & 0xffffff000) + 0x1000;}
这样问题就解决了。
而实际上向上取整还有改进的“窍门“,那就是
i = (i + 0xfff) & 0xfffff000;
上面讨论的是对二进制和十六进制进行而入,那么对于对于我们所处理的十进制也能用“与运算”吗?
以向下取整为例,我们可以归纳出 i = i & (0x100000000 - 向下舍入单位)。按照这个思路如果以100为单位进行向下舍入,就可以按照 i = i & (0x100000000 - 100),即 i = i &oxffffff9c来竖立。但这样做并不成功,假设i = 123,结果是24,没有得到我们的预期答案。
不愿轻易放弃的人可以尝试更多的计算,不过没有一个会是成功的,因为不能用“与运算”来进行十进制的舍入处理。
这倒不是说无法对二进制和十六进制以外的数进行向下舍入处理,只不过不能用“与运算”。可以用其他方法,如 i = (i/100)*100,我们还可以改进,写成i = i - (i%100),这种方法只用了除法和减法运算,比既用除法又用乘法要快。
不管采用以上哪种方法,在以2^n(n>0)以外的数为单位进行舍入处理时,都必须用除法命令,而它恰恰是CPU最不好处理的指令之一,所以要花费较长的时间,而与运算是CPU命令中最快的命令之一,和除法相比要快10到100倍。