java数字超过long.max_值-如何检测?
我在检测两个数字的和/乘是否超过长整数的最大值时遇到问题。java数字超过long.max_值-如何检测?,java,numbers,Java,Numbers,我在检测两个数字的和/乘是否超过长整数的最大值时遇到问题。 示例代码: long a = 2 * Long.MAX_VALUE; System.out.println("long.max * smth > long.max... or is it? a=" + a); 这给了我-2,而我希望它抛出NumberFormatException 有没有一种简单的方法可以让它工作?因为我有一些代码在嵌套的IF块中进行乘法,或者在循环中进行加法,我不想在每个IF或循环中添加更多的IF 编辑:哦,好
示例代码:
long a = 2 * Long.MAX_VALUE;
System.out.println("long.max * smth > long.max... or is it? a=" + a);
这给了我-2
,而我希望它抛出NumberFormatException
有没有一种简单的方法可以让它工作?因为我有一些代码在嵌套的IF块中进行乘法,或者在循环中进行加法,我不想在每个IF或循环中添加更多的IF
编辑:哦,好吧,另一个问题的答案似乎最适合我的需要:我不想做装箱/拆箱,因为这会增加不必要的开销,而且这种方式非常短,这对我来说是一个巨大的优势。我将只编写两个短函数来执行这些检查,并返回min或max long 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));
}
/**
*@param a:两个相加/相乘的数字之一
*@param b:两个数字中的另一个
*@param c:加法/乘法的结果
*@如果a和b的加法/乘法小于long.MIN_值或大于long.MAX_值,则返回长整数的最小值或最大值
*/
公共静态长限长(长a、长b、长c)
{
返回((a>0)和&(b>0)和&(c=0))?Long.MIN_值:c);
}
如果你认为这是错误的,请告诉我。如果你不能确定结果将少于9万亿万亿,我将使用
double
或biginger
获取错误对你没有多大帮助,因为你仍然需要知道如何处理
通过验证输入以确保它们在范围内,并且如果结果的范围大于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);
有了双倍,你就能做到
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
代替long可能会导致精度损失
首先,我希望避免使用错误块。超过long的最大值不会抛出异常,而是返回。如果您这样做:
Long.MAX\u值+1
您会注意到结果相当于Long.MIN\u值
如果希望它引发异常,请检查它是否达到最大值并引发异常
[编辑]
您还可以使用库检查两个long求和时是否存在溢出
long c = LongMath.checkedAdd(a, b);
当发生溢出时,这会引发异常
您可以发现javadoc
Long
值超过MAX\u值
不会引发任何异常。您需要手动检查和处理此类情况
虽然A. @彼得法瑞建议你应该考虑使用<代码>双< /代码>和<代码> BigInteger < /代码> .< /p>如果需要,请将其修剪成<代码>长> >。也许有帮助?在我的情况下,得到一个错误会有很大帮助;我可以将整个代码放在一个try/catch块中,如果抛出错误,请将该值设置为Long.MAX\u值,因为这就是我所需要的。如果它超过Long,则无法修剪它。你能做的最好的事情就是把它设置为
Long。MAX\u VALUE
,这不是一个很好的解决方案。@PeterLawrey我想把它设置为Long。MAX\u VALUE
是OP将它缩减为Long
“只需做一个if检查,看看它是否达到了最大值”——你怎么想?确切地说,我不想自己抛出异常,我不应该抛出异常;如果对2求和时出现溢出,则抛出异常longs@DanielA. 也许你应该补充一点,你需要这个。唉,一个图书馆只是为了这不是我感兴趣的。。。我不敢相信Java忽略了这些东西;正如你所说,当逻辑结果应该是溢出时,我绝对没有理由“循环它回去”。可能是一些没有人想清理的遗留代码…不同意。这是一个非常深思熟虑和完全合理的呼吁,要求溢出只取低位。对于初学者来说,任何替代方案都会为Java中的每个算术运算带来巨大的性能开销。处理器就是这样做的,就这些事情而言,Java的行为是相对合理的。应该有一些允许整数溢出检测的库。或者特殊的块(比如finally?),可以帮助开发人员为在中执行的所有数学代码启用错误溢出行为。我相信C#有一个。编辑:找到了。嗯,C#似乎在溢出上抛出错误(我更喜欢沉默和错误的结果,这对我来说没有意义)…添加了一个检查最小/最大溢出的函数,有人可以查看它吗?可能是重复的,你如何使用双精度?已经发布了一个BigInteger示例,但是double。。。将Long.MAX_值的值指定两倍并打印它,会得到9.223372036854776E18
。