计算机语言mod(m n),关于一段地址对齐的位运算代码的解释

#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //为了满足需要内存对齐的系统

这段代码有些难以理解。那么慢慢分析下吧。

假设有一个地址n,要把n按m对齐,无非就是找到大于等于n且整除m的最小的那个数。

我们定义一个宏函数F,它计算n按m对齐的结果,则按照上段代码的逻辑,F定义为:

#define F(n, m) (n+m-1)&~(m-1)

这段代码如果不用这种按位与来写,其实可以这么写:

#define F(n, m) (n+m-1)/m*m

以上的做法正确性可以分情况证明:

(为了说明问题方便,由于计算机里的除法和严格的数学意义上的除法是不一样的,我们这里以"/"表示计算机里的除法,"%"表示严格的数学除法,"mod"表示取模运算。之后也遵循这个惯例,只是代码还是遵循计算机语言本身的规范。)

1.如果n是能整除m的,那么结果应该就是n,能得出F(n, m)的结果正确;

2.如果n不能整除m,那么结果应该是n - n mod m + m。由于n - n mod m + m能整除m,所以我们只需要证(n - n mod m + m)/m等于(n+m-1)/m。也即证

0<= (n+m-1) - (n - n mod m + m) < m

上面这个式子很显然。

当我们反过来再看计算机里的除法"/"时,发现,实际上,对于被除数x与除数y,有:

x/y = (x - x mod y) % y

设a=n+m-1,有

(n+m-1)/m*m = a/m*m = (a - a mod m)%m*m = a - a mod m

实际上,只要证

a&~(m-1) = a - a mod m

当然,这里的前提是,m是2的幂次。

这里假设m=2^q。那么m的二进制表示一定是1后面跟q个0。m-1则为最后面q位为1,前面全为0,按位取反结果是后面q位为0,前面为1。

由于m是2的幂次,故a mod m结果就是a的二进制表示的最后q位结果。而a按位与一个前面全为1后q位为0的二进制数,则正好就是减去了后q位,等同于减去a对m的余数。

故得证。

原文:http://www.cnblogs.com/waytofall/p/4109514.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值