Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java数字超过long.max_值-如何检测?_Java_Numbers - Fatal编程技术网

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