167 votes

Puis-je convertir un long en int ?

Je veux convertir long a int .

Si la valeur de long > int.MaxValue je suis heureux de la laisser s'enrouler autour.

Quel est le meilleur moyen ?

240voto

Mehrdad Afshari Points 204872

Fais-le. (int)myLongValue . Il fera exactement ce que vous voulez (rejeter les MSB et prendre les LSB) en unchecked (qui est le contexte par défaut du compilateur). Il lancera OverflowException en checked si la valeur ne rentre pas dans un contexte de int :

int myIntValue = unchecked((int)myLongValue);

17 votes

Pour tous ceux qui ont eu la même question que moi : Notez que le fait d'éliminer les MSBs peut avoir un effet sur le résultat de l'opération. signe du résultat. Avec ce qui précède, myIntValue peut devenir négatif lorsque myLongValue est positif ( 4294967294 => -2 ) et vice-versa ( -4294967296 => 0 ). Ainsi, lors de la mise en œuvre d'un CompareTo par exemple, vous ne pouvez pas utiliser le résultat de la soustraction d'une valeur de long d'un autre à un int et le retourner ; pour certaines valeurs, votre comparaison donnerait un résultat incorrect.

23 votes

@Chris : new Random() utilise Environment.TickCount sous le capot ; il n'est pas nécessaire d'ensemencer manuellement avec des tics d'horloge.

3 votes

Le contexte par défaut est unchecked donc, à moins que vous ne l'ayez explicitement modifié, le paramètre unchecked (comme indiqué dans cette réponse et dans le commentaire de @ChrisMarisic, etc.) n'est pas nécessaire, et int myIntValue = (int)myLongValue est exactement équivalent. Cependant, notez que, que vous utilisiez ou non la fonction unchecked ou non, vous obtenez le comportement de troncature grossier non mathématique décrit par @T.J.Crowder où le signe peut s'inverser dans certains cas de débordement. La seule façon de garantir une correction mathématique est d'utiliser le mot-clé checked(...) où ces cas déclencheront une exception.

43voto

Max Schmeling Points 6295
Convert.ToInt32(myValue);

Mais je ne sais pas ce qu'il fera quand il sera supérieur à int.MaxValue.

50 votes

"Bien que je ne sache pas ce qu'il fera quand il sera plus grand que int.MaxValue" Il lancera un OverflowException ce qui est exactement ce que le PO ne veut pas : msdn.microsoft.com/fr/us/library/d4haekc4.aspx

5 votes

Testez si myValue > Integer.Max avant d'exécuter le convert, si vous devez effectuer d'autres traitements lorsque myValue > Integer.Max. Convert.ToInt32(myValue) débordera (sans exception, je crois) sinon. Cette méthode fonctionne également en VB.NET.

3 votes

Bien que (int) soit valable, Convert est une meilleure réponse. Il vaut mieux avoir des exceptions bizarres que des données bizarres.

17voto

realbart Points 294

Parfois, vous n'êtes pas réellement intéressé par la valeur réelle, mais par son utilisation en tant que somme de contrôle/code de hachage . Dans ce cas, la méthode intégrée GetHashCode() est un bon choix :

int checkSumAsInt32 = checkSumAsIn64.GetHashCode();

8 votes

Cette réponse n'a pas été donnée depuis longtemps, mais je tiens à mentionner que l'implémentation du code de hachage peut différer entre les versions de .NET. Il se peut que ce ne soit pas le cas, mais il n'y a aucune garantie que cette valeur soit la même entre les différentes exécutions d'applications/domaines d'applications.

1 votes

Pour ajouter à ce que dit @Caramiriel : si vous l'utilisez en tant que temporaire pendant la session de l'application en cours. GetHashCode est un choix approprié. Si vous recherchez un somme de contrôle persistante - une valeur qui sera la même lorsque vous exécuterez votre application plus tard, alors n'utilisez pas GetHashCode car il n'est pas garanti que ce soit toujours le même algorithme.

12voto

Mashake Points 1

Le moyen le plus sûr et le plus rapide est d'utiliser Bit Masking avant de couler...

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

Le masque de bits ( 0xFFFFFFFF ) dépendra de la taille de Int car la taille de Int dépend de la machine.

0 votes

Vous devez décider ce qui doit se passer lorsque le résultat déborde ou devient un nombre négatif. Ce que vous montrez débordera toujours, IIRC, parce que vous laissez passer le bit de signe. [Comme mentionné dans une autre réponse, en unchecked vous n'obtiendrez pas de débordement - mais vous n'avez pas besoin de masquer dans le contexte unchecked pour éviter le débordement, une solution n'est donc nécessaire que dans les cas suivants checked contexte]. Exemple pour 16-bits. Les 16 bits signés contiennent (-32768, 32767). Le masquage avec 0xFFFF permet une valeur jusqu'à 65535, provoquant un débordement, IIRC. On pourrait masquer pour éviter le bit de signe, 0x7FFF ou 0x7FFFFFFF, si l'on veut du positif uniquement.

10voto

Andre Points 47

Une solution possible est d'utiliser l'opérateur modulo pour que les valeurs restent uniquement dans la plage int32, puis de les convertir en int.

var intValue= (int)(longValue % Int32.MaxValue);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X