看书笔记,整数除法的编译优化
1.除法,公式中的c一般称为MAGIC_NUM
(1)有符号数除法,除数为2^n
数学优化公式:
if (x >= 0):
x / 2^n = x>>n
else:
x / 2^n = (x + (2 ^ n - 1)) >> n
(2)有符号数除法,除数为-2^n
数学优化公式:
if (x >= 0):
x / -2^n = -(x>>n)
else:
x / -2^n = -((x + (2 ^ n - 1)) >> n)
(3)有符号数除法,除数为正非2^n
数学优化公式1:
- 32位除法:
if (x >= 0):
x / o = x * c >> 32 >>n
else:
x / o = (x * c >> 32 >> n) + 1
- 64位除法:
if (x >= 0):
x / o = x * c >> 64 >>n
else:
x / o = (x * c >> 64 >> n) + 1
c为正数(二进制最高位为0),n可能为0
数学优化公式2:
- 32位除法:
if (x >= 0):
x / o = (x * c >> 32) + x >> n
else:
x / o = ((x * c >> 32) + x >> n) + 1
- 64位除法:
if (x >= 0):
x / o = (x * c >> 64) + x >> n
else:
x / o = ((x * c >> 64) + x >> n) + 1
c为负数
o = 2^n / c, n 为 右移总次数
(4)有符号数除法,除数为负非2^n
数学优化公式1:
- 32位除法:
if (x >= 0):
x / o = x * c >> 32 >>n
else:
x / o = (x * c >> 32 >> n) + 1
- 64位除法:
if (x >= 0):
x / o = x * c >> 64 >>n
else:
x / o = (x * c >> 64 >> n) + 1
c为负数(二进制最高位为1),n可能为0
数学优化公式2:
- 32位除法:
if (x >= 0):
x / o = (x * c >> 32) - x >> n
else:
x / o = ((x * c >> 32) - x >> n) + 1
- 64位除法:
if (x >= 0):
x / o = (x * c >> 64) - x >> n
else:
x / o = ((x * c >> 64) - x >> n) + 1
c为正数
32位:|o| = 2^n / (2^32 - c), 64位:|o| = 2^n / (2^64 - c) ,n 为 右移总次数
(5)无符号数除法,除数为2^n, 略
(6)无符号数除法,除数为非2^n
数学优化公式:
- 32位除法:
x / o = x * c >> 32 >> n
- 64位除法:
x / o = x * c >> 64 >> n
o = 2 ^ (32 + n)/ c , (32 + n)为右移总次数;64位同理
(7)无符号数除法,除数为非2^n b
数学优化公式:
- 32位除法:
x / o = (x - (x * c >> 32) >> n1) + (x * c >> 32) >> n2
- 64位除法:
x / o = (x - (x * c >> 64) >> n1) + (x * c >> 64) >> n2
o = 2 ^ (32 + n)/ 2^32 + c , n = n1 + n2;64位同理
2.求余
(1)取模运算,除数为2^n
公式1:
if (x >= 0):
x % 2^n = x & (2^n - 1)
else:
x % 2^n = (x & (2^n - 1)) - 1 | (~(2^n - 1)) + 1
公式2:
if (x >= 0):
x % 2^n = x & (2^n - 1)
else:
x % 2^n = (x + (2^n - 1) & (2^n - 1)) - (2^n - 1)
(1)取模运算,除数为非2^n
余数 = 被除数 - 商 * 除数
优化公式:
x % c = x - x / c * c
x/c会被优化,根据乘数c快速识别