2012-03-27 4 views
107

Можно ли это сделать?Как проверить, является ли double целое число

double variable; 
variable = 5; 
/* the below should return true, since 5 is an int. 
if variable were to equal 5.7, then it would return false. */ 
if(variable == int) { 
    //do stuff 
} 

Я знаю, что код, вероятно, ничего подобного не идти, но как делает это пойти?

+1

C#, но аналогичный в Java: http://stackoverflow.com/a/4077262/284240 ([Integer.MAX_VALUE] (http://docs.oracle.com/javase/1.4.2/docs/api/java /lang/Integer.html#MAX_VALUE)) –

+1

Что бы вы получили от этого? 'double' и' int' представляются в памяти по-разному, и вы будете использовать тот или иной вариант в зависимости от контекста вашей обработки памяти. – Makoto

+0

if (num% 1 == 0) –

ответ

95
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) { 
    // integer type 
} 

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

Ваша переменная может иметь значение int или double, а Math.floor(variable) всегда имеет значение int, поэтому, если ваша переменная равна Math.floor(variable), тогда она должна иметь значение int.

Это также не работает, если значение переменной бесконечно или отрицательно бесконечно, поэтому добавление «до тех пор, пока переменная не является inifinite» условию.

+3

«Если аргумент NaN или бесконечность или положительный нуль или отрицательный ноль, то результат будет таким же, как и аргумент». http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#floor%28double%29 –

+2

@TimSchmelter: хороший улов. Стоит также отметить, что NaN не является чем-то равным (включая себя), но +/- Inf равно себе - так что есть два крайних случая! – maerics

+0

Оба Скона и Фуада опубликовали гораздо лучшие ответы. –

15
public static boolean isInt(double d) 
{ 
    return d == (int) d; 
} 
0
public static boolean isInteger(double d) { 
    // Note that Double.NaN is not equal to anything, even itself. 
    return (d == Math.floor(d)) && !Double.isInfinite(d); 
} 
+0

Более правильная реализация вернет false, и вам придется написать другой метод, который принимает int как аргумент и возвращает true. : D – alfa

+0

@alfa: lol, good one =) – maerics

63

гуавы: DoubleMath.isMathematicalInteger. (Раскрытие: я написал это.) Или, если вы еще не импортируете Guava, x == Math.rint(x) - это самый быстрый способ сделать это; rint измеряется быстрее, чем floor или ceil.

+2

Не знаю насчет Math.rint Вы правы. Это намного быстрее, чем Math.floor –

+3

Это должен быть принятый ответ. – leventov

+0

Это как-то предпочтительнее для примера литья Э.Фуада? –

153

Или вы могли бы использовать оператор по модулю:

(d % 1) == 0

+1

Мне очень нравится простота этого решения. Он легко читается и реализуется. – krispy

+1

Очень интуитивно понятное решение –

+2

Что касается вычислений, то это быстрее, чем 'Math.rint (d)'? – iTurki

0

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

public final double testRange = 0.2; 

public static boolean doubleIsInteger(double d){ 
    int i = (int)d; 
    double abs = Math.abs(d-i); 
    return abs <= testRange; 
} 

Если вы назначили d значение 33.15, метод возвращает true. Чтобы получить лучшие результаты, вы можете назначить более низкие значения testRange (как 0,0002) по своему усмотрению.

4

Попробуйте этот путь,

public static boolean isInteger(double number){ 
    return Math.ceil(number) == Math.floor(number); 
} 

, например:

Math.ceil(12.9) = 13; Math.floor(12.9) = 12; 

, следовательно 12,9 является не целое число, тем не менее,

Math.ceil(12.0) = 12; Math.floor(12.0) =12; 

следовательно 12.0 является целым числом

0

Вот версия для Integer и Double:

private static boolean isInteger(Double variable) { 
    if ( variable.equals(Math.floor(variable)) && 
      !Double.isInfinite(variable)   && 
      !Double.isNaN(variable)    && 
      variable <= Integer.MAX_VALUE   && 
      variable >= Integer.MIN_VALUE) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Для преобразования Double в Integer:

Integer intVariable = variable.intValue(); 
-1

Вот решение:

float var = Your_Value; 
if ((var - Math.floor(var)) == 0.0f) 
{ 
    // var is an integer, so do stuff 
} 
0

Подобно SkonJeet-х ответьте Бова, но производительность лучше (по крайней мере в Java):

Double zero = 0d;  
zero.longValue() == zero.doubleValue() 
0

Лично я предпочитаю простое решение операции по модулю в принятом ответе. К сожалению, SonarQube не любит тесты равенства с плавающими точками без установки округлой точности. Поэтому мы попытались найти более подходящее решение. Вот оно:

if (new BigDecimal(decimalValue).remainder(new BigDecimal(1)).equals(BigDecimal.ZERO)) { 
    // no decimal places 
} else { 
    // decimal places 
} 

Remainder(BigDecimal) возвращает BigDecimal, значение которого (this % divisor). Если это равно нулю, мы знаем, что нет плавающей запятой.

1

Рассмотрим:

Double.isFinite (value) && Double.compare (value, StrictMath.rint (value)) == 0 

Это прилипает к основному Java и избегает сравнения равенства между значениями с плавающей точкой (==), который consdered плохо. isFinite() необходим, поскольку rint() будет передавать значения бесконечности.

Смежные вопросы