专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java修炼终极指南:17. 计算int/long的数学绝对值及结果溢出

temp10 2024-10-24 17:16:16 java教程 13 ℃ 0 评论


数学绝对值是通过在两个管道符号之间放置值来表示的,计算方式如下:

Java修炼终极指南:17. 计算int/long的数学绝对值及结果溢出

|x| = x, |-x| = x

它通常用于计算/表示距离。例如,假设0代表海平面,我们有一个潜水员和一个登山者。潜水员在水下-45英尺(注意我们使用负数来表示潜水员在水下的深度)。同时,登山者攀登了30英尺高。他们中谁离海平面(0)更近?我们可能会认为-45 < 30,所以潜水员更近,因为它的值更小。但是,我们可以通过应用数学绝对值来轻松找到正确答案,如下所示:

|-45| = 45, |30| = 30

45 > 30,所以登山者离海平面(0)更近

现在,让我们通过以下示例深入探讨解决方案:

int x = -3;  
int absofx = Math.abs(x); // 3


这是Math.abs()的一个非常简单的用例,它返回给定整数的数学绝对值。现在,让我们将这种方法应用于以下大数:

int x = Integer.MIN_VALUE; // -2,147,483,648      
int absofx = Math.abs(x);  // 这里会溢出,因为实际结果是-2,147,483,648(这是错误的)


这不好!因为|Integer.MIN_VALUE| > |Integer.MAX_VALUE|,所以int域溢出了。预期的结果是2,147,483,648的正数值,但这不适合int域。然而,将x的类型从int更改为long可以解决这个问题:

long x = Integer.MIN_VALUE; // -2,147,483,648      
long absofx = Math.abs(x);  // 2,147,483,648


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

long y = Long.MIN_VALUE;   // -9,223,372,036,854,775,808  
long absofy = Math.abs(y); // 这里会溢出,因为实际结果是-9,223,372,036,854,775,808(这是错误的)


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

int absofxExact = Math.absExact(x);  // ArithmeticException  
long absofyExact = Math.absExact(y); // ArithmeticException


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

UnaryOperator<Integer> operatorInt = Math::absExact;  
UnaryOperator<Long> operatorLong = Math::absExact;  
// 两者都会抛出ArithmeticException  
int absofxExactUo = operatorInt.apply(x);    
long absofyExactUo = operatorLong.apply(y);


当处理大数字时,还请关注BigInteger(不可变的任意精度整数)和BigDecimal(不可变的任意精度有符号十进制数)。

Tags:

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

欢迎 发表评论:

最近发表
标签列表