Mic*_*ael 30 java math integer overflow
可能重复:
如何检查Java中的两个数字相乘是否会导致溢出?
假设我有一个Java类方法,它使用*和+操作.
int foo(int a, int b) {
... // some calculations with + and *
}
如何确保不会发生溢出foo?
我想我可以使用BigDecimal或替换所有+和*与"包装",如:
int sum(int a, int b) {
int c = a + b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
int prod(int a, int b) {
int c = a * b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
有没有更好的方法来确保intJava方法中不会发生溢出?
Aln*_*tak 23
以检查溢出的一种方式是有操作数升为(双原始操作数位长的)更大的类型然后执行该操作,然后查看是否所得到的值是原始类型,例如过大
int sum(int a, int b) {
long r = (long)a + b;
if (r >>> 32 != 0) { // no sign extension
throw new MyOverflowException(a, b);
}
return (int)r;
}
Run Code Online (Sandbox Code Playgroud)
如果您的原始类型是a long,则必须使用BigInteger更大的类型.
Ste*_*n C 20
从工程角度来看,这是一个难题.
该安全编码的网站建议:
这篇Dobbs博士的文章建议创建一个原始算术方法库,它使用显式溢出检查来执行每个基本操作.(您可以将其视为上面第2点要点的实现.)但作者更进一步建议您使用字节码重写来替换算术字节码,并调用包含溢出检查的等效方法.
不幸的是,没有办法在Java中本机启用溢出检查.(但同样适用于许多其他语言;例如C,C++ ......)
总和:检查b是否大于您可以存储在int中的最大值的差减去a的值.如果a和/或b可以是负数,则必须(i)注意不要为差异检查获得溢出并且(ii)对最小值执行类似的检查.
产品:这更难.我将整数分成两个半长整数(即如果int是32位,使用位掩码和移位将其分成两个16位数).然后进行乘法运算,然后查看结果是否适合32位.
在你不想简单地接受long临时结果的条件下的一切.
| 归档时间: |
|
| 查看次数: |
26630 次 |
| 最近记录: |