java number exceeds long.max_value - how to detect?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-30 08:32:40

问题


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...

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.

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.

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

/**
 * @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.


回答1:


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

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 long use a type which can handle this.

With BigInteger you can do

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 double instead of long can result in some loss of precision.

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




回答2:


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

Long.MAX_VALUE + 1

you will notice that the result is the equivalent to 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 Guava Library to check if there is an overflow when you sum two longs;

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

this throws an exception when an overflow occurs while summing two longs.

You can find the javadoc here




回答3:


Long values exceeding MAX_VALUE doesn't throw any exception. You need to check and handle such situations manually.

ALthough as @PeterLawrey suggested you should consider using double and BigInteger.



来源:https://stackoverflow.com/questions/12348067/java-number-exceeds-long-max-value-how-to-detect

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!