避免算术溢出

时间:2012-02-26 17:24:39

标签: java c math precision

假设您有两个积极的longab,它们大于2^32(并且小于2^63),并且是一个长整数{ {1}}。 在java和\或c中执行

等操作的最佳方法是什么
c

同时避免算术溢出。

编辑: c大约是(a*b)%c ,有时a和b都在2^342^32之间......

我最终避免使用c来处理我所处的特定情况。事实上,有可能知道BigIntegera的一个除数(并非总是如此),所以我会优先使用b的算术属性。

4 个答案:

答案 0 :(得分:8)

假设一切都是正面的,那么你可以使用以下数学标识:

(a*b)%c == ((a%c) * (b%c)) % c

当然,这仍然不能消除溢出的可能性。

完全避免此问题的最简单方法是使用大整数库。

答案 1 :(得分:2)

你可以比@Oli Charlesworth在他的(好)答案中建议的更进一步。您可以分解因子ab(在所有素因子中不必要,部分分解可能就足够了)并在乘法的任何中间结果中执行模数。虽然这可能比购买bignum更昂贵,因为它涉及相当多的部门而且价格昂贵。

答案 2 :(得分:1)

在Java中我会使用BigInteger

BigInteger bd = BigInteger.valueOf(2).pow(33);
System.out.println(bd.multiply(bd).remainder(BigInteger.valueOf(2).pow(34).add(BigInteger.valueOf(1))));

答案 3 :(得分:1)

据我所知,如果没有更高精度的算术,就没有办法解决你的问题,至少LLVM的优化器也同意。

如果128位数学本身不可用,则需要使用通用大整数库,或者从GnuCash中的Math128等不太通用的实现中获取所需的位。