setparsebigdecimal parse convertir castear cast java bigdecimal

java - parse - Compruebe si BigDecimal es un valor entero



string to bigdecimal java 7 (7)

¿Alguien puede recomendar una forma eficiente de determinar si un BigDecimal es un valor entero en el sentido matemático?

En este momento tengo el siguiente código:

private boolean isIntegerValue(BigDecimal bd) { boolean ret; try { bd.toBigIntegerExact(); ret = true; } catch (ArithmeticException ex) { ret = false; } return ret; }

... pero me gustaría evitar la sobrecarga de creación de objetos si es necesario. Anteriormente estaba usando bd.longValueExact() lo que evitaría crear un objeto si BigDecimal estaba usando internamente su representación compacta, pero obviamente fallaría si el valor fuera demasiado grande para caber en un largo.

Cualquier ayuda apreciada.


Dependiendo de la fuente / uso de sus valores de BigDecimal , podría ser más rápido verificar primero si la escala es <= 0. Si lo es, entonces definitivamente es un valor entero en el sentido matemático. Si es> 0, entonces aún podría ser un valor entero y la prueba más costosa sería necesaria.


Divida el número por 1 y verifique el resto. Cualquier número entero siempre debe tener un resto de 0 cuando se divide por 1.

public boolean isWholeNumber(BigDecimal number) { return number.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0; }


EDITAR: a partir de Java 8, stripTrailingZeroes () ahora representa cero

BigDecimal stripTrailingZeros no funciona para cero

Asi que

private boolean isIntegerValue(BigDecimal bd) { return bd.stripTrailingZeros().scale() <= 0; }

Está perfectamente bien ahora.

Si usa la solución scale() y stripTrailingZeros() mencionada en algunas de las respuestas, debe prestar atención a cero. Cero siempre es un número entero sin importar la escala que tenga, y stripTrailingZeros() no altera la escala de un BigDecimal cero.

Entonces podrías hacer algo como esto:

private boolean isIntegerValue(BigDecimal bd) { return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0; }


Este es el más limpio que he encontrado.

public static boolean isWhole(BigDecimal bigDecimal) { return bigDecimal.setScale(0, RoundingMode.HALF_UP).compareTo(bigDecimal) == 0; }


Esto se puede hacer de la misma manera que alguien verificaría si un doble es un número entero, realizando% 1 == 0. Así es como se vería un valor de BigDecimal.

public static boolean isIntegerValue(BigDecimal bd){ return bd.remainder(new BigDecimal("1")).compareTo(BigDecimal.ZERO) == 0; }


Puede usar esto (simplemente resuma de otras respuestas):

private boolean isIntegerValue(BigDecimal bd) { return bd.stripTrailingZeros().scale() <= 0; }


Una posibilidad debería ser comprobar si scale() es cero o negativo. En ese caso, el BigDecimal no debería tener dígitos después del punto decimal y el número debería ser un entero matemático si entiendo su pregunta correctamente.

Actualización : si es positivo, aún podría ser un número entero, pero no se pueden guardar creaciones de objetos adicionales para verificaciones adicionales en ese caso. Un ejemplo de este caso se da en el método javadoc stripTrailingZeros() (agradece a Joachim la pista en su respuesta).