有没有办法,我可以编写以下行,这比当前表达式更有效?
Math.abs(((a*k + b) % P) % m);
P
是一个常数素数
m
是非负面的,是2的力量
a
和b
是随机非负数
注意:要明确,这不是我在分析过程中发现的热点,我想改进。我的兴趣在于找到是否有一种方法可以更好地(在效率方面)编写表达式,例如,对于具有更好位操作背景的人来说,这可能很容易知道。
答案 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的幂时,模数除法。
当前面的结果是否定的时候出现差异,因为这种方法将消极视为正面。