Réponses:
Fais juste (int)myLongValue
. Il fera exactement ce que vous voulez (en supprimant les MSB et en prenant des LSB) en unchecked
contexte (ce qui est la valeur par défaut du compilateur). Cela mettra OverflowException
en checked
contexte si la valeur ne rentre pas dans un int
:
int myIntValue = unchecked((int)myLongValue);
new Random()
utilise Environment.TickCount
sous le capot; pas besoin de semer manuellement avec des tics d'horloge.
unchecked
donc, à moins que vous ne l'ayez explicitement modifié, le unchecked
mot - clé (comme indiqué dans cette réponse et le commentaire de @ ChrisMarisic, etc.) n'est pas nécessaire et int myIntValue = (int)myLongValue
est exactement équivalent. Cependant , ne note que peu importe si vous utilisez le unchecked
mot - 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
Convert
n'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();
GetHashCode
c'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.
unchecked
contexte, vous n'obtiendrez pas de débordement - mais vous n'avez pas besoin de vous masquer unchecked
pour éviter le débordement, donc une solution n'est nécessaire que dans le checked
contexte.] 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?
longValue
plus proche représentable int
si 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.MinValue
aussi. L'affiche originale ne semblait pas vouloir de serrage, cependant.
myIntValue
peut finir négatif quandmyLongValue
est positif (4294967294 => -2
) et vice-versa (-4294967296 => 0
). Ainsi, lors de l'implémentation d'uneCompareTo
opération, par exemple, vous ne pouvez pas convertir le résultat de la soustractionlong
de l'un à l'autre en unint
et le renvoyer; pour certaines valeurs, votre comparaison donnerait un résultat incorrect.