Desbordamientos silenciosos de números en Java
- Desbordamiento de métodos exactos matemáticos en Java
- AddExact vs suma regular en Java
- Desbordamiento de enteros en Java
- Operaciones aritméticas seguras en Java
Considera este ejemplo:
int result = Integer.MAX_VALUE + 1;
// Resulta en Integer.MIN_VALUE debido al desbordamiento
En operaciones aritméticas regulares, cuando ocurre un desbordamiento, Java silenciosamente da la vuelta, lo que lleva a errores difíciles de detectar.
Métodos exactos de Java
Suma segura
Math.addExact() realiza la suma y lanza una ArithmeticException si el resultado causaría desbordamiento. Está disponible tanto para tipos int como long:
try {
int result = Math.addExact(Integer.MAX_VALUE, 1);
} catch (ArithmeticException e) {
System.out.println("¡La suma causaría desbordamiento!");
}
Multiplicación segura
Similar a addExact, multiplyExact maneja operaciones de multiplicación de forma segura:
try {
int result = Math.multiplyExact(100000, 100000);
} catch (ArithmeticException e) {
System.out.println("¡La multiplicación causaría desbordamiento!");
}
También hay uno para long.
Resta segura
subtractExact asegura operaciones de resta seguras:
try {
int result = Math.subtractExact(Integer.MIN_VALUE, 1);
} catch (ArithmeticException e) {
System.out.println("¡La resta causaría desbordamiento!");
}
Otros métodos aritméticos exactos
Java también proporciona varios otros métodos aritméticos exactos:
incrementExact – incrementa en uno, lanza ArithmeticException:
int result = Math.incrementExact(Integer.MAX_VALUE);
decrementExact – decrementa en uno, lanza ArithmeticException:
int result = Math.decrementExact(Integer.MIN_VALUE);
negateExact – devuelve la negación del argumento, lanza ArithmeticException:
int result = Math.negateExact(Integer.MIN_VALUE);
toIntExact – devuelve el valor del argumento long, lanza ArithmeticException:
Convierte un long a int, lanzando una excepción si el valor no puede ser representado como int:
int result = Math.toIntExact(Long.MAX_VALUE);
Aplicaciones
Estos métodos son particularmente útiles en:
- Cálculos financieros donde la precisión es crucial
- Cálculos científicos que no pueden tolerar desbordamiento
- Aplicaciones críticas para la seguridad
- Escenarios de validación de entrada
Mejores prácticas
- Use métodos exactos cuando trabaje con entrada no confiable
- Implemente un manejo adecuado de excepciones al usar estos métodos
- Considere usar
BigIntegeroBigDecimalpara números enormes
Ejemplo de patrón de uso
Aquí hay un ejemplo práctico que combina varios métodos exactos:
public class SafeCalculator {
public static int calculateTotal(int quantity, int price) {
try {
// Primero multiplicar cantidad y precio
int subtotal = Math.multiplyExact(quantity, price);
// Agregar impuesto (asumiendo 10%)
int tax = Math.multiplyExact(subtotal, 10);
tax = Math.divideExact(tax, 100);
// Devolver total con impuesto
return Math.addExact(subtotal, tax);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("El cálculo causaría desbordamiento", e);
}
}
}