8

我在检测两个数字的和/乘是否超过长整数的最大值时遇到问题。
示例代码:

long a = 2 * Long.MAX_VALUE;
System.out.println("long.max * smth > long.max... or is it? a=" + a);

这给了我-2,虽然我希望它会抛出一个NumberFormatException......

有没有一种简单的方法来完成这项工作?因为我有一些代码在嵌套的 IF 块中进行乘法运算或在循环中进行加法运算,我不想在每个 IF 或循环内添加更多的 IF。

编辑:哦,好吧,似乎另一个问题的答案最适合我的需要:https
: //stackoverflow.com/a/9057367/540394 我不想装箱/拆箱,因为它增加了不必要的开销,而且这条路很短,这对我来说是一个巨大的优势。我将编写两个简短的函数来进行这些检查并返回最小或最大长度。

Edit2:根据我上面链接的答案,这是将 long 限制为其最小值/最大值的函数:

/**
 * @param a : one of the two numbers added/multiplied
 * @param b : the other of the two numbers
 * @param c : the result of the addition/multiplication
 * @return the minimum or maximum value of a long integer if addition/multiplication of a and b is less than Long.MIN_VALUE or more than Long.MAX_VALUE
 */
public static long limitLong(long a, long b, long c)
{
    return (((a > 0) && (b > 0) && (c <= 0))
        ? Long.MAX_VALUE
        : (((a < 0) && (b < 0) && (c >= 0)) ? Long.MIN_VALUE : c));
}

如果您认为这是错误的,请告诉我。

4

3 回答 3

5

超过 long 的最大值不会引发异常,而是会返回。如果你这样做:

Long.MAX_VALUE + 1

你会注意到结果等同于Long.MIN_VALUE

如果您希望它抛出异常,请检查它是否达到最大值并抛出异常

[编辑]

您还可以使用Guava Library 检查两个 long 相加时是否溢出;

long c = LongMath.checkedAdd(a, b);

这会在发生溢出时引发异常。

你可以在这里找到 javadoc

于 2012-09-10T08:50:03.553 回答
5

如果你不能确定结果会小于 9 万亿,我会使用doubleor BigIntegerGetting an error 对你没有多大帮助,因为你仍然需要知道该怎么做。

更好的是,通过验证输入以确保它们在范围内并且结果的范围大于long使用可以处理此问题的类型,您首先不会遇到错误。

使用 BigInteger,您可以做到

BigInteger a = BigInteger.valueOf(2).multiply(BigInteger.valueOf(Long.MAX_VALUE));
long l = a.longValue();
if (a.compareTo(BigInteger.valueOf(l)) == 0) {
    // ok
} else {
    // error
}

使用 double 你可以做到

double d = 2.0 * Long.MAX_VALUE;
long l = (long) Math.max(Long.MIN_VALUE, Math.min(Long.MAX_VALUE, d));
// or as a helper method.
long l = boundedCast(d);

注意:使用double而不是 long 可能会导致一些精度损失。

我宁愿首先避免需要错误块。

于 2012-09-10T08:46:24.287 回答
0

Long超出的值MAX_VALUE不会引发任何异常。您需要手动检查和处理此类情况。

尽管@PeterLawrey 建议您应该考虑使用doubleand BigInteger

于 2012-09-10T08:53:15.130 回答