Voglio convertire long
in int
.
Se il valore di long
> int.MaxValue
, sono felice di lasciarlo avvolgere.
Qual è il modo migliore?
Voglio convertire long
in int
.
Se il valore di long
> int.MaxValue
, sono felice di lasciarlo avvolgere.
Qual è il modo migliore?
Risposte:
Fallo e basta (int)myLongValue
. Farà esattamente quello che vuoi (scartando MSB e prendendo LSB) nel unchecked
contesto (che è l'impostazione predefinita del compilatore). Sarà gettare OverflowException
nel checked
contesto se il valore non rientra in una int
:
int myIntValue = unchecked((int)myLongValue);
new Random()
utilizza Environment.TickCount
sotto il cofano; non è necessario eseguire il seeding manuale con i segni di spunta dell'orologio.
unchecked
, quindi a meno che tu non l'abbia modificato esplicitamente, la unchecked
parola chiave (come mostrato in questa risposta e nel commento di @ ChrisMarisic, ecc.) Non è necessaria ed int myIntValue = (int)myLongValue
è esattamente equivalente. Tuttavia, tieni presente che, indipendentemente dal fatto che tu usi unchecked
o meno la parola chiave, stai ottenendo il comportamento di troncamento non matematico descritto da @TJCrowder in cui il segno può capovolgere in alcuni casi di overflow. L'unico modo per garantire veramente la correttezza matematica è utilizzare il checked(...)
contesto, in cui tali casi genereranno un'eccezione.
Convert.ToInt32(myValue);
Anche se non so cosa farà quando è maggiore di int.MaxValue.
OverflowException
, che è esattamente ciò che l'OP non vuole: msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convert
non va bene.
if (value > Int32.MaxValue)
return Int32.MaxValue;
else
return Convert.ToInt32( value );
A volte non sei effettivamente interessato al valore reale, ma al suo utilizzo come checksum / hashcode . In questo caso, il metodo integrato GetHashCode()
è una buona scelta:
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
GetHashCode
è una scelta appropriata. Se stai cercando un checksum persistente , un valore che sarà lo stesso quando eseguirai l'app in un secondo momento, non utilizzarlo GetHashCode
, poiché non è garantito che sia lo stesso algoritmo per sempre.
Il modo più sicuro e veloce è usare Bit Masking prima del cast ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
Il 0xFFFFFFFF
valore Maschera bit ( ) dipenderà dalla dimensione di Int poiché la dimensione Int dipende dalla macchina.
unchecked
contesto non si otterrà un overflow - ma non è necessario mascherare unchecked
per evitare l'overflow, quindi una soluzione è necessaria solo nel checked
contesto.] Esempio per 16 bit. Hold a 16 bit con segno (-32768, 32767). La mascheratura con 0xFFFF consente un valore fino a 65535, causando overflow, IIRC. Potrebbe mascherare per evitare bit di segno, 0x7FFF o 0x7FFFFFFF, se si desidera solo positivo.
Può convertire da
Metodo Convert.ToInt32
Ma genererà una OverflowException se il valore è al di fuori dell'intervallo del tipo Int32. Un test di base ci mostrerà come funziona:
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.
Qui c'è una spiegazione più lunga.
non sarebbe
(int) Math.Min(Int32.MaxValue, longValue)
essere nel modo corretto, matematicamente parlando?
longValue
più vicino rappresentabile int
se il valore originale è troppo grande. Ma manca lo stesso trattamento di input troppo negativi, che perderebbe invece i bit più significativi; dovresti confrontare Int32.MinValue
anche. Il poster originale non sembrava voler essere bloccato, però.
myIntValue
può risultare negativo quandomyLongValue
è positivo (4294967294 => -2
) e viceversa (-4294967296 => 0
). Quindi, quando si implementaCompareTo
un'operazione, per esempio, non si può felicemente lanciare il risultato sottraendo l'unolong
dall'altroint
e restituirlo; per alcuni valori, il confronto produrrebbe un risultato errato.