Quiero convertirme long
a int
.
Si el valor de long
> int.MaxValue
, estoy feliz de dejarlo envolver.
¿Cuál es la mejor manera?
Quiero convertirme long
a int
.
Si el valor de long
> int.MaxValue
, estoy feliz de dejarlo envolver.
¿Cuál es la mejor manera?
Respuestas:
Solo hazlo (int)myLongValue
. Hará exactamente lo que desee (descartar MSB y tomar LSB) en unchecked
contexto (que es el valor predeterminado del compilador). Se lanzará OverflowException
en checked
contexto si el valor no cabe en un int
:
int myIntValue = unchecked((int)myLongValue);
new Random()
usos Environment.TickCount
debajo del capó; No es necesario sembrar manualmente con los tics del reloj.
unchecked
, entonces, a menos que lo haya cambiado explícitamente, entonces la unchecked
palabra clave (como se muestra en esta respuesta y el comentario de @ ChrisMarisic, etc.) no es necesaria, y int myIntValue = (int)myLongValue
es exactamente equivalente. Sin embargo, tenga en cuenta que independientemente de si usa la unchecked
palabra clave o no, está obteniendo el comportamiento de truncamiento grosero no matemático descrito por @TJCrowder, donde el signo puede voltearse en algunos casos de desbordamiento. La única forma de garantizar realmente la corrección matemática es utilizar el checked(...)
contexto, donde esos casos arrojarán una excepción.
Convert.ToInt32(myValue);
Aunque no sé qué hará cuando sea mayor que int.MaxValue.
OverflowException
, que es exactamente lo que el OP no quiere: msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convert
no es bueno.
if (value > Int32.MaxValue)
return Int32.MaxValue;
else
return Convert.ToInt32( value );
A veces no estás realmente interesado en el valor real, sino en su uso como suma de comprobación / código hash . En este caso, el método incorporado GetHashCode()
es una buena opción:
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
GetHashCode
es una opción adecuada. Si busca una suma de comprobación persistente , un valor que será el mismo cuando ejecute su aplicación más tarde, no lo use GetHashCode
, ya que no se garantiza que sea el mismo algoritmo para siempre.
La forma más segura y rápida es usar Bit Masking antes de lanzar ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
El 0xFFFFFFFF
valor de Máscara de bits ( ) dependerá del tamaño de Int porque el tamaño Int depende de la máquina.
unchecked
contexto no obtendrá un desbordamiento, pero no necesita enmascararse unchecked
para evitar el desbordamiento, por lo que solo se necesita una solución en checked
contexto.] Ejemplo para 16 bits. Presas firmadas de 16 bits (-32768, 32767). El enmascaramiento con 0xFFFF permite valores de hasta 65535, lo que provoca un desbordamiento, IIRC. Podría enmascarar para evitar el bit de signo, 0x7FFF o 0x7FFFFFFF, si solo desea positivo.
Se puede convertir por
Método Convert.ToInt32
Pero arrojará una Excepción de desbordamiento si el valor está fuera del rango del Tipo Int32. Una prueba básica nos mostrará cómo funciona:
long[] numbers = { Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue };
int result;
foreach (long number in numbers)
{
try {
result = Convert.ToInt32(number);
Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
number.GetType().Name, number,
result.GetType().Name, result);
}
catch (OverflowException) {
Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.",
number.GetType().Name, number);
}
}
// The example displays the following output:
// The Int64 value -9223372036854775808 is outside the range of the Int32 type.
// Converted the Int64 value -1 to the Int32 value -1.
// Converted the Int64 value 0 to the Int32 value 0.
// Converted the Int64 value 121 to the Int32 value 121.
// Converted the Int64 value 340 to the Int32 value 340.
// The Int64 value 9223372036854775807 is outside the range of the Int32 type.
Aquí hay una explicación más larga.
No
(int) Math.Min(Int32.MaxValue, longValue)
ser la forma correcta, matemáticamente hablando?
longValue
representable más cercano int
si el valor original es demasiado grande. Pero carece del mismo tratamiento de entradas demasiado negativas, lo que en su lugar perdería los bits más significativos; Tendría que comparar con Int32.MinValue
también. Sin embargo, el póster original no parecía querer sujetarlo.
myIntValue
puede terminar negativo cuandomyLongValue
es positivo (4294967294 => -2
) y viceversa (-4294967296 => 0
). Por lo tanto, al implementar unaCompareTo
operación, por ejemplo, no puede emitir felizmente el resultado de restar unolong
de otro a unint
y devolverlo; para algunos valores, su comparación arrojaría un resultado incorrecto.