round parse cast java casting

parse - Casting seguro largo a int en Java



round double to int java (10)

Afirmo que la forma obvia de ver si la conversión de un valor cambió el valor sería emitir y verificar el resultado. Sin embargo, eliminaría el lanzamiento innecesario al comparar. Tampoco estoy demasiado interesado en los nombres de las variables de una letra (excepción x e y , pero no cuando significan fila y columna (a veces respectivamente)).

public static int intValue(long value) { int valueInt = (int)value; if (valueInt != value) { throw new IllegalArgumentException( "The long value "+value+" is not within range of the int type" ); } return valueInt; }

Sin embargo, realmente me gustaría evitar esta conversión si es posible. Obviamente, a veces no es posible, pero en esos casos, IllegalArgumentException es casi con toda seguridad la excepción errónea que se debe lanzar en lo que respecta al código del cliente.

¿Cuál es la forma más idiomática en Java para verificar que una conversión de long a int no pierde ninguna información?

Esta es mi implementación actual:

public static int safeLongToInt(long l) { int i = (int)l; if ((long)i != l) { throw new IllegalArgumentException(l + " cannot be cast to int without changing its value."); } return i; }


Aquí hay una solución, en caso de que no te importe el valor en caso de que sea más grande de lo necesario;)

public static int safeLongToInt(long l) { return (int) Math.max(Math.min(Integer.MAX_VALUE, l), Integer.MIN_VALUE); }


Con BigDecimal:

long aLong = ...; int anInt = new BigDecimal(aLong).intValueExact(); // throws ArithmeticException // if outside bounds


Con la clase Ints Google Guava, su método se puede cambiar a:

public static int safeLongToInt(long l) { return Ints.checkedCast(l); }

De los documentos vinculados:

verificado

public static int checkedCast(long value)

Devuelve el valor int que es igual al value , si es posible.

Parámetros: value - cualquier valor en el rango del tipo int

Devuelve: el valor int que es igual al value

Emite: IllegalArgumentException - si el value es mayor que Integer.MAX_VALUE o menor que Integer.MIN_VALUE

Por cierto, no necesita el envoltorio safeLongToInt , a menos que desee dejarlo en su lugar para cambiar la funcionalidad sin una refactorización extensa, por supuesto.


Creo que lo haría tan simple como:

public static int safeLongToInt(long l) { if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) { throw new IllegalArgumentException (l + " cannot be cast to int without changing its value."); } return (int) l; }

Creo que eso expresa la intención más claramente que el reparto repetido ... pero es algo subjetivo.

Nota de interés potencial: en C # simplemente sería:

return checked ((int) l);


Los tipos enteros de Java se representan como firmados. Con una entrada entre 2 31 y 2 32 (o -2 31 y -2 32 ) la conversión tendría éxito pero su prueba fallaría.

Lo que hay que verificar es si todos los bits altos del long son todos iguales:

public static final long LONG_HIGH_BITS = 0xFFFFFFFF80000000L; public static int safeLongToInt(long l) { if ((l & LONG_HIGH_BITS) == 0 || (l & LONG_HIGH_BITS) == LONG_HIGH_BITS) { return (int) l; } else { throw new IllegalArgumentException("..."); } }


Otra solución puede ser:

public int longToInt(Long longVariable) { try { return Integer.valueOf(longVariable.toString()); } catch(IllegalArgumentException e) { Log.e(e.printstackstrace()); } }

He intentado esto en los casos en los que el cliente realiza una POST y la base de datos del servidor solo comprende enteros mientras que el cliente tiene un valor largo.


Se ha agregado un nuevo método con Java 8 para hacer precisamente eso.

import static java.lang.Math.toIntExact; long foo = 10L; int bar = toIntExact(foo);

Lanzará una ArithmeticException en caso de desbordamiento.

Ver: Math.toIntExact(long)

Varios otros métodos seguros de desbordamiento se han agregado a Java 8. Terminan con exacto .

Ejemplos:

  • Math.incrementExact(long)
  • Math.subtractExact(long, long)
  • Math.decrementExact(long)
  • Math.negateExact(long),
  • Math.subtractExact(int, int)

NO: ¡Esto no es una solución!

Mi primer acercamiento fue:

public int longToInt(long theLongOne) { return Long.valueOf(theLongOne).intValue(); }

Pero eso simplemente convierte el largo en un int, potencialmente creando nuevas instancias de Long o recuperándolas del Long pool.

Los inconvenientes

  1. Long.valueOf crea una nueva instancia de Long si el número no está dentro del rango de la agrupación de Long [-128, 127].

  2. La implementación de intValue no hace nada más que:

    return (int)value;

Por lo tanto, esto puede considerarse incluso peor que simplemente lanzar el long al int .


(int) (longType + 0)

pero largo no puede exceder el máximo :)