java java数量超过long.max_value - 如何检测?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12348067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:31:05  来源:igfitidea点击:

java number exceeds long.max_value - how to detect?

javanumbers

提问by jurchiks

I'm having problems detecting if a sum/multiplication of two numbers exceeds the maximum value of a long integer.
Example code:

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

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

This gives me -2, while I would expect it to throw a NumberFormatException...

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

Is there a simple way of making this work? Because I have some code that does multiplications in nested IF blocks or additions in a loop and I would hate to add more IFs to each IF or inside the loop.

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

Edit: oh well, it seems that this answer from another question is the most appropriate for what I need: https://stackoverflow.com/a/9057367/540394
I don't want to do boxing/unboxing as it adds unnecassary overhead, and this way is very short, which is a huge plus to me. I'll just write two short functions to do these checks and return the min or max long.

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

Edit2: here's the function for limiting a long to its min/max value according to the answer I linked to above:

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));
}

Tell me if you think this is wrong.

告诉我你是否认为这是错误的。

回答by Peter Lawrey

If you can't be sure the result will be less than 9 trillion trillion, I would use doubleor BigIntegerGetting an error doesn't help you very much because you still need to know what to do about.

如果您不能确定结果会小于 9 万亿,我会使用doubleBigInteger获取错误对您没有太大帮助,因为您仍然需要知道该怎么做。

Much better that you don't get an error in the first place by validating your input to ensure they are in range and if the range of the result is larger than longuse a type which can handle this.

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

With BigInteger you can do

使用 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
}

With double you can do

用双你可以做

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);

Note: using doubleinstead of long can result in some loss of precision.

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

I would prefer to avoid the need for an error block in the first place.

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

回答by Daniel André

Exceding the maximum value of a long doesnt throw an exception, instead it cicles back. If you do this:

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

Long.MAX_VALUE + 1

Long.MAX_VALUE + 1

you will notice that the result is the equivalent to Long.MIN_VALUE

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

If you want it to throw an exception check if it reached the max value and throw the exception

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

[Edit]

[编辑]

You can also use the GuavaLibrary to check if there is an overflow when you sum two longs;

也可以使用GuavaLibrary来检查两个long相加时是否有溢出;

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

this throws an exception when an overflow occurs.

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

You can find the javadoc here

你可以在这里找到 javadoc

回答by Bharat Sinha

Longvalues exceeding MAX_VALUEdoesn't throw any exception. You need to check and handle such situations manually.

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

ALthough as @PeterLawrey suggested you should consider using doubleand BigInteger.

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