Réponses:
Fais juste (int)myLongValue. Il fera exactement ce que vous voulez (en supprimant les MSB et en prenant des LSB) en uncheckedcontexte (ce qui est la valeur par défaut du compilateur). Cela mettra OverflowExceptionen checkedcontexte si la valeur ne rentre pas dans un int:
int myIntValue = unchecked((int)myLongValue);
new Random()utilise Environment.TickCountsous le capot; pas besoin de semer manuellement avec des tics d'horloge.
uncheckeddonc, à moins que vous ne l'ayez explicitement modifié, le uncheckedmot - clé (comme indiqué dans cette réponse et le commentaire de @ ChrisMarisic, etc.) n'est pas nécessaire et int myIntValue = (int)myLongValueest exactement équivalent. Cependant , ne note que peu importe si vous utilisez le uncheckedmot - clé ou non, vous obtenez le comportement de troncature grossier non-mathématique décrit par @TJCrowder où le signe peut retourner dans certains cas de débordement. La seule façon de vraiment garantir l'exactitude mathématique est d'utiliser le checked(...)contexte, où ces cas lèveront une exception.
Convert.ToInt32(myValue);
Bien que je ne sache pas ce qu'il fera quand il est supérieur à int.MaxValue.
OverflowException, ce qui est exactement ce que l'OP ne veut pas: msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convertn'est pas bon.
if (value > Int32.MaxValue) return Int32.MaxValue; else return Convert.ToInt32( value );
Parfois, vous n'êtes pas vraiment intéressé par la valeur réelle, mais par son utilisation comme somme de contrôle / hashcode . Dans ce cas, la méthode intégrée GetHashCode()est un bon choix:
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
GetHashCodec'est un choix approprié. Si vous recherchez une somme de contrôle persistante - une valeur qui sera la même lorsque vous exécuterez votre application plus tard, ne l'utilisez pas GetHashCode, car il n'est pas garanti que ce soit le même algorithme pour toujours.
Le moyen le plus sûr et le plus rapide est d'utiliser le masquage de bits avant de lancer ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
La valeur Bit Mask ( 0xFFFFFFFF) dépendra de la taille de Int car la taille Int dépend de la machine.
uncheckedcontexte, vous n'obtiendrez pas de débordement - mais vous n'avez pas besoin de vous masquer uncheckedpour éviter le débordement, donc une solution n'est nécessaire que dans le checkedcontexte.] Exemple pour 16 bits. Signé 16 bits détient (-32768, 32767). Le masquage avec 0xFFFF permet une valeur jusqu'à 65535, provoquant un débordement, IIRC. Pourrait masquer pour éviter le bit de signe, 0x7FFF ou 0x7FFFFFFF, si vous voulez seulement positif.
Il peut convertir en
Méthode Convert.ToInt32
Mais il lèvera une OverflowException si la valeur est en dehors de la plage du type Int32. Un test de base nous montrera comment cela fonctionne:
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.
Ici, il y a une explication plus longue.
Ne serait pas
(int) Math.Min(Int32.MaxValue, longValue)
être la bonne manière, mathématiquement parlant?
longValueplus proche représentable intsi la valeur d'origine est trop grande. Mais il lui manque le même traitement des entrées trop négatives, qui perdraient à la place les bits les plus significatifs; vous auriez besoin de comparer Int32.MinValueaussi. L'affiche originale ne semblait pas vouloir de serrage, cependant.
myIntValuepeut finir négatif quandmyLongValueest positif (4294967294 => -2) et vice-versa (-4294967296 => 0). Ainsi, lors de l'implémentation d'uneCompareToopération, par exemple, vous ne pouvez pas convertir le résultat de la soustractionlongde l'un à l'autre en unintet le renvoyer; pour certaines valeurs, votre comparaison donnerait un résultat incorrect.