用整数乘法和模数改善表达式

时间:2015-07-11 15:54:32

标签: java optimization integer bit-manipulation modulo

有没有办法,我可以编写以下行,这比当前表达式更有效?

Math.abs(((a*k + b) % P) % m);  

P是一个常数素数
m是非负面的,是2的力量 ab是随机非负数

注意:要明确,这不是我在分析过程中发现的热点,我想改进。我的兴趣在于找到是否有一种方法可以更好地(在效率方面)编写表达式,例如,对于具有更好位操作背景的人来说,这可能很容易知道。

2 个答案:

答案 0 :(得分:2)

总结评论链,你可以写

.getCertificateAlias(Certificate)

等同于原始表达式,但无论如何都符合相同的要求。它处理(a * k + b) % P & (m - 1) 为负的情况(因为a * k + b是负的或因为包装而不同),但是对于散列函数来说仍然很好。

在这个新表达式中,唯一剩下的mod操作是一个常量,任何可敬的编译器都会沿着相同的行进行优化,因为它优化除以常量。

答案 1 :(得分:1)

这得到了一个类似的答案("类似的"表示"当括号表达式为非负时相同,但在负数时不同),但使用位功夫来避免模数除法Math.abs()的调用:

(a*k + b) % P & ~-m

要查看正在进行的操作,请假设m = 8并查看16位位模式:

8   -> 0000 1000
-8  -> 1111 1000
~-8 -> 0000 0111

正如您所看到的,~-m产生的位掩码需要屏蔽除n % m结果所需的所有位 - 即高位(负指示位)和除了位为1位右侧的位用于2位数的幂。

就个人而言,我非常迷恋表达式~-m,当与前面的计算进行AND运算时,abs()(通过高位比特屏蔽)实现了当m是2的幂时,模数除法。

当前面的结果是否定的时候出现差异,因为这种方法将消极视为正面。