Ich möchte konvertieren long
zu int
.
Wenn der Wert long
> ist int.MaxValue
, lasse ich ihn gerne herumlaufen.
Was ist der beste Weg?
c#
types
int
type-conversion
long-integer
trotz
quelle
quelle
myIntValue
kann negativ enden, wennmyLongValue
positiv (4294967294 => -2
) ist und umgekehrt (-4294967296 => 0
). Wenn Sie beispielsweise eineCompareTo
Operation implementieren , können Sie das Ergebnis der Subtraktionlong
von einer Operation nicht glücklich in eineint
umwandeln und diese zurückgeben. Bei einigen Werten würde Ihr Vergleich zu einem falschen Ergebnis führen.new Random()
verwendetEnvironment.TickCount
unter der Haube; Keine Notwendigkeit, manuell mit Uhrzecken zu säen.unchecked
Sie ihn nicht explizit geändert haben, wird dasunchecked
Schlüsselwort (wie in dieser Antwort und im Kommentar von @ ChrisMarisic usw. gezeigt) nicht benötigt undint myIntValue = (int)myLongValue
ist genau gleichwertig. Beachten Sie jedoch, dass unabhängig davon, ob Sie dasunchecked
Schlüsselwort verwenden oder nicht, das von @TJCrowder beschriebene nicht-mathematische Verhalten beim unhöflichen Abschneiden angezeigt wird, bei dem das Vorzeichen in einigen Überlauffällen umdrehen kann. Die einzige Möglichkeit, die mathematische Korrektheit wirklich sicherzustellen, besteht darin, denchecked(...)
Kontext zu verwenden, in dem diese Fälle eine Ausnahme auslösen.Obwohl ich nicht weiß, was es tun wird, wenn es größer als int.MaxValue ist.
quelle
OverflowException
, was genau das ist, was das OP nicht will: msdn.microsoft.com/en-us/library/d4haekc4.aspxConvert
nicht gut.if (value > Int32.MaxValue)
return Int32.MaxValue;
else
return Convert.ToInt32( value );
Manchmal interessiert Sie der tatsächliche Wert nicht wirklich, sondern seine Verwendung als Prüfsumme / Hashcode . In diesem Fall ist die integrierte Methode
GetHashCode()
eine gute Wahl:quelle
GetHashCode
ist dies eine geeignete Wahl. Wenn Sie nach einer dauerhaften Prüfsumme suchen - ein Wert, der beim späteren Ausführen Ihrer App gleich bleibt, verwenden Sie ihn nichtGetHashCode
, da nicht garantiert wird, dass er für immer derselbe Algorithmus ist.Der sicherste und schnellste Weg ist die Verwendung der Bitmaskierung vor dem Wirken ...
Der
0xFFFFFFFF
Wert für Bit Mask ( ) hängt von der Größe von Int ab, da die Größe von Int von der Maschine abhängt.quelle
unchecked
Kontext keinen Überlauf - Sie müssen sich jedoch nicht maskierenunchecked
, um den Überlauf zu vermeiden. Daher wird eine Lösung nur imchecked
Kontext benötigt .] Beispiel für 16-Bit. Vorzeichenbehaftete 16-Bit-Holds (-32768, 32767). Das Maskieren mit 0xFFFF ermöglicht einen Wert von bis zu 65535, was zu einem Überlauf (IIRC) führt. Könnte maskieren, um Vorzeichenbit, 0x7FFF oder 0x7FFFFFFF zu vermeiden, wenn nur positiv gewünscht wird.Es kann konvertieren durch
Es wird jedoch eine OverflowException ausgelöst, wenn der Wert außerhalb des Bereichs des Int32-Typs liegt. Ein grundlegender Test zeigt uns, wie es funktioniert:
Hier gibt es eine längere Erklärung.
quelle
Würde nicht
mathematisch gesehen der richtige Weg sein?
quelle
longValue
,int
wenn der ursprüngliche Wert zu groß ist. Es fehlt jedoch die gleiche Behandlung von zu negativen Eingaben, die stattdessen die höchstwertigen Bits verlieren würden. Sie müssten auch mit vergleichenInt32.MinValue
. Das Originalplakat schien jedoch keine Klemmung zu wollen.Die folgende Lösung wird auf int.MinValue / int.MaxValue abgeschnitten, wenn der Wert außerhalb der Ganzzahlgrenzen liegt.
quelle
Eine Möglichkeit besteht darin, den Modulo-Operator zu verwenden, um nur die Werte im int32-Bereich zu belassen, und ihn dann in int umzuwandeln.
quelle