Определение целочисленности double в Java: сравнение и приведение типов
Быстрый ответ
Для мгновенной проверки целочисленности значения типа double
сопоставьте его с округленной версией посредством Math.rint()
или проверьте отсутствие дробной части с помощью Math.floor()
. Важно учесть бесконечные значения, чтобы избежать нежелательных проблем.
double value = // ваше значение типа double
boolean isInteger = (value == Math.rint(value)) && !Double.isInfinite(value);
// Этим образом можно определить, является ли значение типа double целым числом. Можно использовать и другой метод...
boolean isInteger = (value == Math.floor(value)) && value != Math.ceil(value);
// Этот вариант работает также корректно. Выбор за вами.
Оба варианта подтверждают, что у числа типа double
отсутствует дробная часть и оно не бесконечно, что является признаками целого числа.
Откроем завесу тайны: Рассмотрим крайние ситуации
Метод приведения типов
Сопоставление значения double
с его приведённым в int
вариантом — примитивная идея, но она требует осмысленности: не все числа могут без ошибок пройти этап приведения.
double value = // ваше значение типа double
boolean isInteger = (value == (int)value) && !Double.isInfinite(value);
Этот метод быстр и прост, однако у него есть ограничения, особенно при работе с большими числами, которые выходят за пределы типа int
.
Точность при сравнении
Особенности арифметики с плавающей запятой могут подстерегать: незначительные ошибки округления могут исказить конечный результат.
final double EPSILON = 1E-10; // незначительное отклонение для сравнения
double value = // ваше значение типа double
boolean isInteger = Math.abs(value – Math.rint(value)) < EPSILON && !Double.isInfinite(value);
Мы ввели корректирующий фактор в проверку равенства, чтобы учесть возможное отклонение. Это хитрый прием при работе с числами типа double
.
Вспомогательные библиотеки
Библиотека Google Guava предлагает удобный утилитарный метод для проверки, является ли double
математически целым числом:
import com.google.common.math.DoubleMath;
...
double value = // ваше значение типа double
boolean isInteger = DoubleMath.isMathematicalInteger(value);
Этот подход избавляет от многих трудностей, связанных с арифметикой плавающей точки, но он требует подключения сторонней библиотеки.
Визуализация
Рассмотрим проверку целочисленности значения типа double
на простом примере:
Парковочное место (🅿️): Предназначено только для целых чисел (Integer).
Автомобиль (🚗): Олицетворяет наше значение типа `double`.
Сценарий: Проверяем, поместится ли автомобиль на парковочном месте:
double value = 3.0; // Наш автомобиль 🚗
boolean isInteger = (value % 1 == 0); // Проверяем, подходит ли место 🅿️
Если автомобиль (value
) идеально вписывается в парковочное место:
🚗🅿️ (3.0) 🟢: Парковка выполнена успешно, число является целым!
Если автомобиль не уместился:
🚗🅿️ (3.14) 🔴: Не подходит, число не является целым!
Ключевая идея: Как и автомобиль, идеально вписывающийся в парковочное место, значение типа double
, которое делится на 1 без остатка, является целым числом.
Расширенные знания: Точность — залог успеха
Работа с исключительными случаями: NaN и бесконечности
Для точной проверки важно учесть случаи с значениями NaN и бесконечными числами:
double value = // ваше значение типа double
boolean isInteger = !Double.isNaN(value) && !Double.isInfinite(value) && (value == Math.floor(value));
Необходимо, чтобы double
было не только целым числом, но и допустимым числовым значением.
Выбор подходящего метода
Важно подобрать метод, наиболее подходящий для конкретной задачи:
Math.rint()
иMath.floor()
идеально подходят для большинства случаев.- Приведение типов эффективно, но не работает с большими числами.
DoubleMath.isMathematicalInteger()
от Google Guava умело обходит типичные проблемы.- Сравнение с использованием дельты полезно при точных вычислениях.
Каждый инструмент имеет свои преимущества в определенных условиях, поэтому ваш выбор должен быть обоснованным.
Полезные материалы
- Double (Java Platform SE 8 ) — официальная документация Java для класса
Double
. - How to test if a double is an integer – Stack Overflow — коллективное обсуждение различных методов в практике.
- Primitive Data Types (The Java™ Tutorials) — руководство по базовым типам данных в Java.
- Math (Java Platform SE 8 ) — официальная документация по методу
Math.floor
. - JDK 21 Documentation – Home — последняя версия официальной документации Java, в которой могут содержаться актуальные рекомендации.
- NumberUtils (Apache Commons Lang 3.11 API) — инструменты для работы с числами от Apache Commons.
- How to compare two double values in Java? – Stack Overflow — обсуждение сложностей, связанных с сравнением значений типа
double
.