2009-05-13 35 views

Respuesta

170

Solo haz (int)myLongValue. Hará exactamente lo que quiera (descartando MSB y tomando LSB) en el contexto unchecked (que es el valor por defecto del compilador). Se va a lanzar en OverflowExceptionchecked contexto si el valor no se ajusta en un int:

int myIntValue = unchecked((int)myLongValue); 
+12

Para cualquier otra persona que haya tenido la misma pregunta que yo: tenga en cuenta que descartar los MSB puede tener un efecto en el * signo * del resultado. Con lo anterior, 'myIntValue' puede terminar negativo cuando' myLongValue' es positivo ('4294967294 => -2') y viceversa (' -4294967296 => 0'). Por lo tanto, al implementar una operación 'CompareTo', por ejemplo, no puede lanzar felizmente el resultado de restar un' long' de otro a un 'int' y devolver eso; para algunos valores, su comparación arrojaría un resultado incorrecto. –

+18

+1 usado en 'nuevo Aleatorio (desmarcado ((int) DateTime.Now.Ticks))' –

+16

@Chris: 'new Random()' usa 'Environment.TickCount' debajo del capó; no es necesario sembrar manualmente con marcas de reloj. –

25
Convert.ToInt32(myValue); 

Aunque no sé lo que hará cuando es mayor que int.MaxValue.

+34

* "Aunque no sé qué hará cuando sea mayor que int.MaxValue" * Lanzará una 'OverflowException', que es exactamente lo que el OP no desea: http://msdn.microsoft.com /en-us/library/d4haekc4.aspx –

+4

Pruebe if myValue> Integer.Max antes de ejecutar la conversión, si necesita hacer otro procesamiento cuando myValue> Integer.Max. Convert.ToInt32 (myValue) se desbordará (sin excepción, creo) de lo contrario. Este método también funciona en VB.NET. – TamusJRoyce

+3

Mientras que (int) es válido, Convertir es una mejor respuesta. Mejor tener extrañas excepciones que datos extraños. –

13

A veces no está realmente interesado en el valor real, pero en su uso como checksum/hashcode. En este caso, el método integrado GetHashCode() es una buena opción:

int checkSumAsInt32 = checkSumAsIn64.GetHashCode(); 
+5

Ha pasado tiempo desde que se dio esta respuesta, aunque quiero Mencione que la implementación del código hash puede diferir entre las versiones .NET. Esto podría no estar sucediendo en realidad, pero no hay garantía de que este valor sea el mismo entre ejecuciones/aplicaciones diferentes. – Caramiriel

+1

Para agregar a lo que dice @Caramiriel: si se usa como un hashcode * temporal *, durante la sesión actual de la aplicación, entonces 'GetHashCode' es una opción adecuada. Si busca una * suma de verificación * persistente *, un valor que será el mismo cuando ejecute su aplicación más tarde, entonces no use 'GetHashCode', ya que no se garantiza que sea el mismo algoritmo para siempre. – ToolmakerSteve

6

La manera más segura y más rápida es utilizar enmascaramiento de bits antes de fundición ...

int MyInt = (int) (MyLong & 0xFFFFFFFF) 

la máscara de bits (0xFFFFFFFF) el valor dependerá del tamaño de Int porque el tamaño de Int depende de la máquina.

+0

Necesita decidir lo que quiere que suceda cuando el resultado se desborde o se convierta en un número negativo. Lo que muestre se seguirá desbordando, IIRC, porque está dejando pasar el letrero. [Como se menciona en otra respuesta, en el contexto 'no verificado' no obtendrás un desbordamiento, pero no necesitas enmascarar en 'desactivado' para evitar el desbordamiento, por lo que solo se necesita una solución en el contexto 'marcado'.] Ejemplo para 16 bits Firmado de 16 bits se mantiene (-32768, 32767). El enmascaramiento con 0xFFFF permite un valor de hasta 65535, causando un desbordamiento, IIRC. Podría enmascarar para evitar el bit de signo, 0x7FFF o 0x7FFFFFFF, si solo quiere positivo. – ToolmakerSteve