使用位运算优化除数为2的幂的有符号除法


之前介绍过一种使用乘法指令优化无符号除法的方式(见hacker's delight笔记), 今天介绍一种使用位运算做有符号除法(除数限制为2的幂). 这种方式要求底层支持有符号与无符号右移指令.
记32位被除数为M, 除数为2**N(2的N次幂, N<32), 商为res, 无符号右移指令为ZextShRl(A, Imm), 有符号右移指令为SextShRl(A, Imm), 无符号左移指令为ZextShlf(A, Imm), 则由以下指令序列可得res(M / 2**N):
S = ZextShRl(M, 0x1F)
S1 = ZextShlf(S, N)
S2 = addi(S1, -1)
M1 = addi(M, S2)
res = SextShRl(M1, N)
证明如下:
首先S即M的符号位(M>0时S=1, 否则S=0), 因此当M>0时即普通右移操作. 我们记M=B[31:0](B为M的每一位组成的数组), 则当M<0时, 有M=B31.B[30:0](其中B31为1), 则SextShRl(M, N)为1[31:31-N].B[30:N].
对于正整数M右移操作为floor(M/N), 由补码运算知负整数M右移操作为ceiling(M/N). 又c标准要求是向零取整, 需要先将M(的绝对值)向下对齐, 即M1=M+S2=-(abs(M)-S2).

以上算法对除数为2的幂的有符号除法有一定优化价值, 尤其是除数为2时以上指令序列可以减少至三条, 大大提升除法运算效率.

posted @ 2018-10-17 00:22  Five100Miles  阅读(684)  评论(0编辑  收藏  举报