es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué no se verifica el desbordamiento de rango al convertir de “Number” a “Float” o “Double” en el código fuente del framework Spring Boot?

Por favor, revise el fragmento de código fuente que se encuentra en org.springframework.util.NumberUtils#convertNumberToTargetClass(), la firma del método es + T convertNumberToTargetClass(number:Number, targetClass:Class)

public static T convertNumberToTargetClass(Number number, Class targetClass)
throws IllegalArgumentException {
… …
… …
else if (Float.class == targetClass) {
return (T) Float.valueOf(number.floatValue());
}
…. ….
…. ….
}

Cuando se convierte “number” a “Float”, no se verifica si “number” sobrepasa el rango de “Float” o no. Pero sí se verifica al convertir “number” a “Byte”, “Integer” o “Short”, como se muestra a continuación:

public static T convertNumberToTargetClass(Number number, Class targetClass)
throws IllegalArgumentException {
… …
… …
else if (Byte.class == targetClass) {
long value = checkedLongValue(number, targetClass);
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
raiseOverflowException(number, targetClass);
}
return (T) Byte.valueOf(number.byteValue());
}
… …
… …
}

private static long checkedLongValue(Number number, Class targetClass) {
BigInteger bigInt = null;
if (number instanceof BigInteger) {
bigInt = (BigInteger) number;
}
else if (number instanceof BigDecimal) {
bigInt = ((BigDecimal) number).toBigInteger();
}
// Efectivamente análogo a BigInteger.longValueExact() en JDK 8
if (bigInt != null && (bigInt.compareTo(LONG_MIN) < 0 || bigInt.compareTo(LONG_MAX) > 0)) {
raiseOverflowException(number, targetClass);
}
return number.longValue();
}

private static void raiseOverflowException(Number number, Class targetClass) {
throw new IllegalArgumentException(“No se pudo convertir el número [” + number + “] del tipo [” +
number.getClass().getName() + “] a la clase objetivo [” + targetClass.getName() + “]: desbordamiento”);
}

¡Tengo mucha curiosidad por saber por qué!

Tags:  ,

Answer

  1. Avatar for davy.ai

    La razón por la que el método convertNumberToTargetClass no verifica si hay desbordamiento al convertir a Float es porque Float es un número de punto flotante IEEE 754 de precisión simple de 32 bits, cuyo rango ya está limitado. Puede representar valores que van desde aproximadamente 1,4 × 10⁻⁴⁵ hasta 3,4 × 10³⁸. Por lo tanto, es muy poco probable que ocurra un desbordamiento al convertir a Float desde cualquier otro tipo numérico.

    Por otro lado, al convertir a Byte, Integer o Short, que tienen un rango más estrecho que Float, hay una mayor probabilidad de que ocurra un desbordamiento. Por lo tanto, el método convertNumberToTargetClass realiza verificaciones de desbordamiento para estos tipos para asegurarse de que el valor convertido pueda caber dentro del rango del tipo objetivo.

    En resumen, el método convertNumberToTargetClass no verifica si hay desbordamiento al convertir a Float porque el rango de Float ya está limitado, mientras que realiza verificaciones de desbordamiento para tipos más estrechos para evitar posibles desbordamientos.

Comments are closed.