专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java修炼终极指南:18. 计算参数的商和结果溢出

temp10 2024-10-11 18:29:19 java教程 16 ℃ 0 评论


让我们从两个简单的计算开始,如下所示:

Java修炼终极指南:18. 计算参数的商和结果溢出

-4/-1 = 4, 4/-1 = -4

这是一个非常简单的用例,按预期工作。现在,让我们保持除数为-1,并将被除数更改为Integer.MIN_VALUE(-2,147,483,648):

int x = Integer.MIN_VALUE;          
int quotient = x/-1; // 结果应该是 2,147,483,648,但这里的结果是 -2,147,483,648


这次结果不正确。因为|Integer.MIN_VALUE| > |Integer.MAX_VALUE|,所以int域溢出了。它应该是正数2,147,483,648,但这不适合int域。但是,将x的类型从int更改为long将解决问题:

long x = Integer.MIN_VALUE;          
long quotient = x/-1; // 2,147,483,648


但是,如果Long.MIN_VALUE替代了Integer.MIN_VALUE,问题将再次出现:

long y = Long.MIN_VALUE; // -9,223,372,036,854,775,808  
long quotient = y/-1;    // 结果是 -9,223,372,036,854,775,808,这是错误的


从JDK 18开始,Math类增加了两个divideExact()方法。一个用于int,一个用于long。如果除法结果倾向于溢出int或long(如Integer/Long.MIN_VALUE溢出正int/long范围),则这些方法非常有用。在这种情况下,这些方法会抛出ArithmeticException,而不是返回一个误导性的结果,如下例所示:

// 抛出ArithmeticException  
int quotientExact = Math.divideExact(x, -1);


在函数式编程风格的上下文中,潜在的解决方案将依赖于BinaryOperator函数式接口,如下所示:

// 抛出ArithmeticException  
BinaryOperator<Integer> operator = Math::divideExact;  
int quotientExactBo = operator.apply(x, -1);


正如我们在上一个问题中所说,当处理大数字时,还要关注BigInteger(不可变的任意精度整数)和BigDecimal(不可变的任意精度有符号十进制数)。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表