我想找到一种方法来知道整数是否除以3或7而不使用除法,因为它在MIPS汇编中非常慢。
我做了很多研究,却一无所获。
答案 0 :(得分:3)
Granlund & Montgomery描述的方法需要(奇数)除数模2**b
的模乘/乘法逆。 (本文的某些部分已得到改进recently)
除数:(d) = 3, 7
(奇数)很容易。假设32位(无符号)算术,反函数2**32
分别产生2863311531 (0xAAAAAAAB)
和3067833783 (0xB6DB6DB7)
。有一个在线计算器here。
我们还需要qmax = (2**32 - 1) / d
值:0x55555555
和0x24924924
resp。
要测试32位(无符号)数字(n)
,请执行单个字乘法 - 也就是说,丢弃完整64位结果的高位字:q = dinv * n
如果(n)
可被(d)
整除,则(q)
必须满足:q * d == n
和 q <= qmax
。如,
int is_divisible_by_3 (uint32_t n)
{
uint32_t q = n * 0xAAAAAAAB;
return (q <= 0x55555555 && (q * 3 == n))
}
用一对单字乘法代替除法/余数。
同样适用于d = 7
。或者,像gcc这样的现代编译器将对为MIPS生成的程序集中的常量除数/模数执行类似的优化,例如if (n % 3 == 0) ...
。
答案 1 :(得分:0)
您可以对各个位的余数求和。 2^n mod 3
与1,2,1,2,...
类似,2^n mod 7
类似1,2,4,1,2,4,...
。
使用查找表使其更快。