2012-09-10 33 views
5

我在检测两个数的和/乘是否超过长整数的最大值时遇到问题。
示例代码:java数量超过long.max_value - 如何检测?

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
我不想做装箱/拆箱,因为它增加unnecassary开销,这种方式是非常总之,这对我来说是一个巨大的优势。我只写两个简短的函数来完成这些检查并返回最小或最大长度。

EDIT2:这里是根据我联系上面的答案限长到它的最小值/最大值功能:

/** 
* @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)); 
} 

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

+0

+1。应该有一些允许整数溢出检测的库。 – Thilo

+0

或者特殊块(类似finally?),它可以帮助开发人员为所有在其中执行的数学代码启用溢出错误行为。我相信C#有一个。编辑:找到它,[在C#中选中和未选中的块](http://msdn.microsoft.com/zh-cn/library/a569z7k8.aspx)。 –

+0

那么,C#似乎抛出溢出错误(我非常喜欢沉默和错误的结果,对我来说没有意义)... – jurchiks

回答

4

如果您不能确定结果会少于9万亿亿,我会使用doubleBigInteger获取错误对您无能为力,因为您仍然需要知道该怎么办。

通过验证输入以确保它们处于范围内,并且如果结果的范围大于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 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,而不是长期可导致一些精度损失。

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

+1

事情是,如果超过它,我需要将其修剪为“长”。也许这有帮助?在我的情况下获得一个错误会有很大帮助;我可以将整个代码放在try/catch块中,如果发生错误,请将该值设置为Long.MAX_VALUE,因为这是我所需要的。 – jurchiks

+0

如果超过了很长时间,则无法修剪。你所能做的最好的就是使它成为'Long.MAX_VALUE',这不是一个好的解决方案。 –

+3

@PeterLawrey我认为将其限制为“Long.MAX_VALUE”是OP的意思是*将其修剪为“long”*。 – brimborium

2

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

Long.MAX_VALUE + 1

你会发现结果是等于Long.MIN_VALUE。

如果你想让它抛出一个异常,检查它是否达到了最大值,并抛出异常

[编辑]

您还可以使用Guava库,以检查是否存在溢出,当你总结两个长期;

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

当总结两个长整数时发生溢出时会引发异常。

你可以找到javadoc的here

+2

“简单地做一个检查是否达到最大值” - 你怎么想的?我不想自己抛出异常,我不应该,确切地说。 – jurchiks

+0

你也可以试试这个:long c = LongMath.checkedAdd(a,b);如果在总结2个多头时出现溢出,则会引发异常 –

+1

@DanielA。也许你应该补充说,你需要[番石榴库](http://code.google.com/p/guava-libraries/)。 – Baz

-1

Long值超过MAX_VALUE不抛出任何异常。您需要手动检查并处理这种情况。

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

+0

你怎么用双重做这个? BigInteger示例已发布,但是双倍...将Long.MAX_VALUE的值赋值为double并打印出来给出了'9.223372036854776E18'。 – jurchiks