有符号非2的幂的第一种优化


\(\frac{x}{c}=x*\frac{2^n}{c}*\frac{1}{2^n}\)

这样就把除法转换为被除数x乘以一个整数,再右移n位的形式,但是有一个问题,因为右移n位是取下整

右移n位是取下整 例子:

? -3/2 = 0xFFFFFFFD / 2 =0xFFFFFFFD >> 1 = 0xFFFFFFFE = 0xFFFFFFFE.1 = -2

由于小数位1被舍去了,所以负数扩大了。

回到正题,当被除数是正数时,自然没问题,但是当被除数是负数时要向上取整才能得到正确的计算结果,所以要在被除数是负数时将去下整转换为去上整

首先将\(\frac{2^n}{c}\)变得略大一些,这样c就会比实际的除数略小一些,能这样做的原因是因为书上的推导6

有整数a,b和实数x且a$ \neq b,b\neq0$

\[-|\frac{1}{b}|\lt x \le 0, \lceil \frac{a}{b}+x\rceil = \lceil \frac{a}{b}\rceil \]

由于c比实际的除数略小于,除数为整数,所以c不等于整数(当a$ \neq 0\(),就满足了a\) \neq b,b\neq0\(的条件,又因被除数为负数,c比实际的除数略小于,所以\)\frac{x}{c}$比实际的值略小,所以才满足上面公式

又因为推导3

当x不为整数

\[\lfloor x \rfloor +1 = \lceil x \rceil \]

由于c不为整数,所以\(\frac{x}{c}\)也不为整数,满足上述公式,所以有下面的推导:

\[\lceil \frac{x}{c} \rceil = \lfloor \frac{x}{c} \rfloor+1 \]

最终得出除数为有符号非2的幂的优化

当x>=0

\[\lfloor\frac{x}{c}\rfloor=\lfloor x*\frac{2^n}{c}*\frac{1}{2^n}\rfloor \]

因为x>0,c比实际的除数略小,所以\(\frac{x}{c}\)比实际的值略大,满足当 \(0 \le x \lt |\frac{1}{b}|,\lfloor \frac{a}{b}+x\rfloor = \lfloor \frac{a}{b}\rfloor\)

注:右边的c要比实际的除数略小

当x<0

\[\lceil\frac{x}{c}\rceil=\lceil x*\frac{2^n}{c}*\frac{1}{2^n}\rceil = \lfloor x*\frac{2^n}{c}*\frac{1}{2^n}\rfloor+1 \]

参考书籍:C++反汇编与逆向分析技术揭秘 第二版