【发布时间】:2012-07-28 15:15:47
【问题描述】:
给定一个奇怪的long x,我正在寻找long y,这样它们的乘积模2**64(即使用正常的溢出算法)等于1。为了明确我的意思:可以计算几千年后这样:
for (long y=1; ; y+=2) {
if (x*y == 1) return y;
}
我知道这可以使用扩展的欧几里得算法快速解决,但它需要能够表示所有涉及的数字(范围高达 2**64,因此即使是无符号算术也无济于事)。使用BigInteger 肯定会有所帮助,但我想知道是否有更简单的方法,可能使用为正长实现的扩展欧几里得算法。
【问题讨论】:
-
Hacker's Delight suggests mod 2^32 的算法。我会尝试一些变体,当然我会进行大量测试。 (也许这可能值得包括在番石榴中......)
-
@Louis Wasserman:很好的链接......与此同时,我认为我的速度提高了 3 倍——我稍后会发布我的结果。顺便说一句,我需要
pow(long, long)(缺少LongMath)作为一种方法。 -
pow(long, long)是故意遗漏的,因为任何不适合int的权力基本上保证会溢出。 (虽然我猜这就是你想要的。) -
是的。对于
checkedPow或saturatedPow之类的东西,我同意长指数没有意义,因为pow我没有。我发布了benchmarks and tests 6 种不同的解决方案可能性。关于番石榴,我建议包括链接的 Math64 中的内容。 -
我们最终采用的规则是我们假设您不想故意导致溢出。
pow和checkedPow的区别不在于它是否会溢出,而在于您是否要支付检查的开销。