Определение целочисленности double в Java: сравнение и приведение типов

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для мгновенной проверки целочисленности значения типа double сопоставьте его с округленной версией посредством Math.rint() или проверьте отсутствие дробной части с помощью Math.floor(). Важно учесть бесконечные значения, чтобы избежать нежелательных проблем.

Java
Скопировать код
double value = // ваше значение типа double
boolean isInteger = (value == Math.rint(value)) && !Double.isInfinite(value);
// Этим образом можно определить, является ли значение типа double целым числом. Можно использовать и другой метод...
boolean isInteger = (value == Math.floor(value)) && value != Math.ceil(value);
// Этот вариант работает также корректно. Выбор за вами.

Оба варианта подтверждают, что у числа типа double отсутствует дробная часть и оно не бесконечно, что является признаками целого числа.

Кинга Идем в IT: пошаговый план для смены профессии

Откроем завесу тайны: Рассмотрим крайние ситуации

Метод приведения типов

Сопоставление значения double с его приведённым в int вариантом — примитивная идея, но она требует осмысленности: не все числа могут без ошибок пройти этап приведения.

Java
Скопировать код
double value = // ваше значение типа double
boolean isInteger = (value == (int)value) && !Double.isInfinite(value);

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

Точность при сравнении

Особенности арифметики с плавающей запятой могут подстерегать: незначительные ошибки округления могут исказить конечный результат.

Java
Скопировать код
final double EPSILON = 1E-10; // незначительное отклонение для сравнения
double value = // ваше значение типа double
boolean isInteger = Math.abs(value – Math.rint(value)) < EPSILON && !Double.isInfinite(value);

Мы ввели корректирующий фактор в проверку равенства, чтобы учесть возможное отклонение. Это хитрый прием при работе с числами типа double.

Вспомогательные библиотеки

Библиотека Google Guava предлагает удобный утилитарный метод для проверки, является ли double математически целым числом:

Java
Скопировать код
import com.google.common.math.DoubleMath;
...
double value = // ваше значение типа double
boolean isInteger = DoubleMath.isMathematicalInteger(value);

Этот подход избавляет от многих трудностей, связанных с арифметикой плавающей точки, но он требует подключения сторонней библиотеки.

Визуализация

Рассмотрим проверку целочисленности значения типа double на простом примере:

Markdown
Скопировать код
Парковочное место (🅿️): Предназначено только для целых чисел (Integer).
Автомобиль (🚗): Олицетворяет наше значение типа `double`.

Сценарий: Проверяем, поместится ли автомобиль на парковочном месте:

Java
Скопировать код
double value = 3.0; // Наш автомобиль 🚗
boolean isInteger = (value % 1 == 0); // Проверяем, подходит ли место 🅿️

Если автомобиль (value) идеально вписывается в парковочное место:

Markdown
Скопировать код
🚗🅿️ (3.0) 🟢: Парковка выполнена успешно, число является целым!

Если автомобиль не уместился:

Markdown
Скопировать код
🚗🅿️ (3.14) 🔴: Не подходит, число не является целым!

Ключевая идея: Как и автомобиль, идеально вписывающийся в парковочное место, значение типа double, которое делится на 1 без остатка, является целым числом.

Расширенные знания: Точность — залог успеха

Работа с исключительными случаями: NaN и бесконечности

Для точной проверки важно учесть случаи с значениями NaN и бесконечными числами:

Java
Скопировать код
double value = // ваше значение типа double
boolean isInteger = !Double.isNaN(value) && !Double.isInfinite(value) && (value == Math.floor(value));

Необходимо, чтобы double было не только целым числом, но и допустимым числовым значением.

Выбор подходящего метода

Важно подобрать метод, наиболее подходящий для конкретной задачи:

  • Math.rint() и Math.floor() идеально подходят для большинства случаев.
  • Приведение типов эффективно, но не работает с большими числами.
  • DoubleMath.isMathematicalInteger() от Google Guava умело обходит типичные проблемы.
  • Сравнение с использованием дельты полезно при точных вычислениях.

Каждый инструмент имеет свои преимущества в определенных условиях, поэтому ваш выбор должен быть обоснованным.

Полезные материалы

  1. Double (Java Platform SE 8 ) — официальная документация Java для класса Double.
  2. How to test if a double is an integer – Stack Overflow — коллективное обсуждение различных методов в практике.
  3. Primitive Data Types (The Java™ Tutorials) — руководство по базовым типам данных в Java.
  4. Math (Java Platform SE 8 ) — официальная документация по методу Math.floor.
  5. JDK 21 Documentation – Home — последняя версия официальной документации Java, в которой могут содержаться актуальные рекомендации.
  6. NumberUtils (Apache Commons Lang 3.11 API) — инструменты для работы с числами от Apache Commons.
  7. How to compare two double values in Java? – Stack Overflow — обсуждение сложностей, связанных с сравнением значений типа double.