Java Math.abs() и Math.absExact() с примерами

Класс Math в Java состоит из методов, выполняющих общие математические операции. Два важных метода в этом классе для обработки абсолютных значений — это Math.abs() и Math.absExact(). В этом руководстве по Java рассматриваются проблемы абсолютных значений, переполнения и потери значимости метода abs() и способы их решения с помощью absExact().

1. Что такое абсолютная величина?

Абсолютное значение действительного числа, часто обозначаемое как |x|, — это неотрицательное значение x независимо от его знака. Другими словами, это расстояние числа от нуля на числовой оси.

Java Math.abs() и Math.absExact() с примерами0

Вот несколько примеров, иллюстрирующих эту концепцию:

  • ∣5∣=5, потому что 5 — положительное число.
  • ∣−8∣=8, потому что абсолютное значение -8 равно 8.
  • ∣0∣=0, поскольку абсолютное значение 0 равно 0.

Абсолютные значения обычно используются для вычисления/выражения расстояний, например, расстояния от уровня моря. Расстояние от уровня моря всегда является положительным числом, независимо от того, ныряет ли аквалангист под воду или альпинист взбирается на гору.

2. Функция Java Math.abs()

Math.abs() используется для получения абсолютного значения числового значения или выражения. Он принимает аргументы типа int, long, float и double.

public static double abs(double a)public static float abs(float a)public static int abs(int a)public static long abs(long a) 

Например, мы можем использовать abs() следующим образом:

double doubleValue = -10.56;float floatValue = -7.8f;int intValue = -15;long longValue = -123456789L;System.out.println(STR."Absolute value of double: \{Math.abs(doubleValue)}");System.out.println(STR."Absolute value of float: \{Math.abs(floatValue)}");System.out.println(STR."Absolute value of int: \{Math.abs(intValue)}");System.out.println(STR."Absolute value of long: \{Math.abs(longValue)}");

Вывод программы:

Absolute value of double: 10.56Absolute value of float: 7.8Absolute value of int: 15Absolute value of long: 123456789 

3. Проблема переполнения/недополнения

Хотя сама по себе функция Math.abs() напрямую не приводит к проблемам переполнения или потери значимости, понимание поведения этой функции имеет решающее значение при работе с большими числовыми значениями, поскольку она может косвенно способствовать возникновению таких проблем.

Рассмотрим следующую программу

int intMinValue = Integer.MIN_VALUE;long longMinValue = Long.MIN_VALUE;System.out.println(STR."Absolute value of int: \{Math.abs(intMinValue)}");System.out.println(STR."Absolute value of long: \{Math.abs(longMinValue)}");

Вывод программы:

 Absolute value of int: -2147483648Absolute value of long: -9223372036854775808

Это нехорошо. Абсолютные значения никогда не должны быть отрицательными. В этих случаях абсолютное значение больше MAX_VALUE, что приводит к проблеме с недорасходом.

Если мы не будем внимательны к таким граничным случаям, мы можем получить неожиданные результаты в программах.

4. Предотвращение переполнения/недополнения с помощью Math.absExact()

Начиная с JDK 15 класс Math был обогащен двумя методами absExact(). Один для int и один для long типов данных. Если математический абсолютный результат склонен к переполнению или недополнению границ int или long, эти методы выдают ArithmeticException вместо возврата вводящего в заблуждение результата.

Давайте повторно запустим предыдущую программу с методом absExact().

System.out.println(STR."Absolute value of int: \{Math.absExact(intMinValue)}");Exception in thread "main" java.lang.ArithmeticException: Overflow to represent absolute value of Integer.MIN_VALUEat java.base/java.lang.Math.absExact(Math.java:1903)at com.howtodoinjava.core.basic.MathAbsoluteExamples.main(MathAbsoluteExamples.java:25)

Для неграничных значений Math.abs() и Math.absExact() работают аналогично.

Если вы все еще используете версию Java ниже 15, вы можете самостоятельно написать проверку для граничного случая следующим образом:

public static int absExact(int a) {if(a == Integer.MIN_VALUE)throw new ArithmeticException("Overflow to represent absolute value of Integer.MIN_VALUE");elsereturn abs(a);}

5. Заключение

Начиная с Java 15 и далее рекомендуется использовать Math.absExact() везде, где вы вычисляете абсолютное значение числа. Это автоматически предотвратит проблемы переполнения и потери значимости. До Java 15 добавьте проверку граничных случаев самостоятельно.

Если вам необходимо работать с очень большими числами или требуется произвольная точность, рассмотрите возможность использования специализированных классов, таких как BigInteger или BigDecimal, которые могут обрабатывать такие сценарии без переполнения или потери значимости.

Исходный код на Githib

Прокрутить вверх