我知道 java.lang.Math 提供了一组静态方法来执行某些操作(sum
,difference
,multiply
,{{1 }},increment
,decrement
,negate
),在溢出时抛出toInt
。
是否有类似的力量?
答案 0 :(得分:9)
不,Java中内置的pow
没有任何等效内容。 (Java中内置的唯一pow
方法是Math.pow
,它接受双精度并且不会以与整数相同的方式溢出,而BigInteger.pow
则不会溢出,因为BigInteger
s可以任意大。)
如果第三方库是可以接受的,那么,番石榴有例如IntMath.checkedPow
,它会执行您正在寻找的内容。
答案 1 :(得分:4)
正如Chirag所说,整数在溢出时会抛出异常而双精度则不会。不要过于具体,但基本上,内存中的双倍存储非常类似于科学记数法,因为它们是一些整数* 2 ^(一些功率),因此永远不会真正溢出而是乘以这么大或小的2 ^(一些力量)他们完全失去了精确度。因此,您可以将双重溢出视为完全失去精确度,并打印为Infinity
或-Infinity
。
因此,您需要通过检查结果值是Double.POSITIVE_INFINITY
还是Double.NEGATIVE_INFINITY
来手动检查是否发生了溢出。
以下是一些展示我的意思的示例代码:
public static void main(String[] args) throws Exception
{
double a = Double.MAX_VALUE; // highest possible double
double b = Double.MAX_VALUE; // highest possible double
if (Math.pow(a, b) == Double.POSITIVE_INFINITY || Math.pow(a, b) == Double.NEGATIVE_INFINITY)
{
throw new ArithmeticException("Double Overflow");
}
}
答案 2 :(得分:1)
如果你自己的实现没问题,你可以这样做:
private static final int[] maxBaseForExponent = IntStream.range(0, 30)
.map(e -> (int) Math.pow(Integer.MAX_VALUE, 1d / e)).toArray();
public static int powExact(int base, int exponent) {
if (exponent < 0) {
throw new ArithmeticException("Negative exponent");
}
if ((base < -1 || base > 1) && (exponent > 30 || base > maxBaseForExponent[exponent])
&& !(base == -2 && exponent == 31)) {
throw new ArithmeticException("Overflow");
}
switch (base) {
case -2:
return (exponent & 1) == 0 ? 1 << exponent : -1 << exponent;
case -1:
return (exponent & 1) == 0 ? 1 : -1;
case 0:
return exponent == 0 ? 1 : 0;
case 1:
return 1;
case 2:
return 1 << exponent;
default:
}
int result = 1;
while (exponent != 0) {
if ((exponent & 1) != 0) {
result *= base;
}
exponent >>= 1;
base *= base;
}
return result;
}
从here获取算法,并使用包含每个指数0到30的最大基数的数组对其进行修改以检查溢出。
答案 3 :(得分:0)
整数只有32位。所以最大值是2 ^ 31 -1。 (如果使用BigInteger.pow
。效率较低。)
因此,您可以手动检查并在需要时抛出异常
否则使用使用double的Math.pow
。