Voglio convertire longin int.
Se il valore di long> int.MaxValue, sono felice di lasciarlo avvolgere.
Qual è il modo migliore?
Voglio convertire longin 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 uncheckedcontesto (che è l'impostazione predefinita del compilatore). Sarà gettare OverflowExceptionnel checkedcontesto se il valore non rientra in una int:
int myIntValue = unchecked((int)myLongValue);
new Random()utilizza Environment.TickCountsotto 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 uncheckedparola 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 uncheckedo 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
Convertnon 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 0xFFFFFFFFvalore Maschera bit ( ) dipenderà dalla dimensione di Int poiché la dimensione Int dipende dalla macchina.
uncheckedcontesto non si otterrà un overflow - ma non è necessario mascherare uncheckedper evitare l'overflow, quindi una soluzione è necessaria solo nel checkedcontesto.] 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?
longValuepiù vicino rappresentabile intse il valore originale è troppo grande. Ma manca lo stesso trattamento di input troppo negativi, che perderebbe invece i bit più significativi; dovresti confrontare Int32.MinValueanche. Il poster originale non sembrava voler essere bloccato, però.
myIntValuepuò risultare negativo quandomyLongValueè positivo (4294967294 => -2) e viceversa (-4294967296 => 0). Quindi, quando si implementaCompareToun'operazione, per esempio, non si può felicemente lanciare il risultato sottraendo l'unolongdall'altrointe restituirlo; per alcuni valori, il confronto produrrebbe un risultato errato.