Cómo probar si un doble es un número entero

¿Es posible hacer esto?

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 } 

Sé que el código probablemente no sea así, pero ¿cómo funciona ?

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

Esto verifica si el valor redondeado del doble es el mismo que el doble.

Su variable podría tener un valor int o double y Math.floor(variable) siempre tiene un valor int, por lo que si su variable es igual a Math.floor(variable) entonces debe tener un valor int.

Esto tampoco funciona si el valor de la variable es infinito o negativo infinito y, por lo tanto, agrega ‘siempre que la variable no sea precisa’ a la condición.

O puede usar el operador de módulo:

(d % 1) == 0

Guava: DoubleMath.isMathematicalInteger . (Divulgación: lo escribí). O, si aún no está importando guayaba, x == Math.rint(x) es la forma más rápida de hacerlo; rint es mensurablemente más rápida que el floor o el ceil .

 public static boolean isInt(double d) { return d == (int) d; } 

Intenta de esta manera,

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

por ejemplo:

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

por lo tanto, 12.9 no es un número entero, sin embargo

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

por lo tanto, 12.0 es un número entero

Considerar:

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

Esto se adhiere al núcleo de Java y evita una comparación de igualdad entre los valores de coma flotante ( == ) que se considera mala. isFinite() es necesario ya que rint() pasará a través de los valores de infinito.

 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); } 

podría intentarlo de esta manera: obtener el valor entero del doble, restarlo del doble valor original, definir un rango de redondeo y probar si el número absoluto del nuevo valor doble (sin la parte entera) es mayor o menor que su rango definido. si es más pequeño puedes intentarlo, es un valor entero. Ejemplo:

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

Si asigna a d el valor 33.15, el método devuelve verdadero. Para obtener mejores resultados, puede asignar valores más bajos a testRange (como 0,0002) a su criterio.

Aquí hay una versión para Integer y 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; } } 

Para convertir de Double a Integer :

 Integer intVariable = variable.intValue(); 

Similar a la respuesta anterior de SkonJeet, pero el rendimiento es mejor (al menos en Java):

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

Personalmente, prefiero la solución de operación de módulo simple en la respuesta aceptada. Desafortunadamente, a SonarQube no le gustan las pruebas de igualdad con puntos flotantes sin establecer una precisión circular. Así que hemos intentado encontrar una solución más compatible. Aquí está:

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

Remainder(BigDecimal) devuelve un BigDecimal cuyo valor es (this % divisor) . Si este es igual a cero, sabemos que no hay punto flotante.

Aquí hay una solución:

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