Konvertierungen von Gleitkomma- in Ganzzahlwerte besitzen jetzt ein Sättigungsverhalten
Konvertierungen von Gleitkomma- in Ganzzahlwerte auf x86- und x64-Computern besitzen jetzt ein Sättigungsverhalten. Das Sättigungsverhalten bedeutet, dass der Wert für den Zieltyp auf den Mindest- oder Höchstwert festgelegt wird, wenn der konvertierte Wert für den Zieltyp zu klein oder zu groß ist.
Vorheriges Verhalten
Die folgende Tabelle zeigt das vorherige Verhalten beim Konvertieren eines float
- oder double
-Werts.
Konvertieren in ... | Wert von x |
Vorheriges Ergebnis |
---|---|---|
int skalar und verpackt |
int.MinValue <= x <= int.MaxValue |
(int)x |
< int.MinValue oder > int.MaxValue |
int.MinValue |
|
long skalar und verpackt |
long.MinValue <= x <= long.MaxValue |
(long)x |
< long.MinValue oder > long.MaxValue |
long.MinValue |
|
uint skalar und verpackt |
Beliebiger Wert | (((long)x << 32) >> 32) |
ulong skalar und verpackt |
<= 2^63 |
(long)x |
> 2^63 |
(long)(x - 2^63) + 2^63 |
Neues Verhalten
Die folgende Tabelle zeigt das neue Verhalten beim Konvertieren eines float
- oder double
-Werts.
Konvertieren in ... | Wert von x |
Ergebnis in .NET 9 und höher |
---|---|---|
int skalar und verpackt |
int.MinValue <= x <= int.MaxValue |
(int)x |
< int.MinValue |
int.MinValue |
|
> int.MaxValue |
int.MaxValue |
|
NaN |
0 | |
long skalar und verpackt |
long.MinValue <= x <= long.MaxValue |
(long)x |
< long.MinValue |
long.MinValue |
|
> long.MaxValue |
long.MaxValue |
|
NaN |
0 | |
uint skalar und verpackt |
0 <= x <= uint.MaxValue |
(uint)x |
x > uint.MaxValue |
uint.MaxValue |
|
x < 0 |
0 | |
ulong skalar und verpackt |
0 <= x <= ulong.MaxValue |
(ulong)x |
x > ulong.MaxValue |
ulong.MaxValue |
|
x < 0 |
0 |
Eingeführt in Version
.NET 9 Preview 4
Typ des Breaking Changes
Diese Änderung ist eine Verhaltensänderung.
Grund für die Änderung
Diese Änderung wurde durchgeführt, um alle Konvertierungen von Gleitkomma- in Ganzzahlwerte so zu standardisieren, dass sie ein Sättigungsverhalten besitzen, und das Verhalten deterministisch zu gestalten.
Empfohlene Maßnahme
Wenn Sie sich bisher darauf verlassen haben, dass nach der Konvertierung die Werte im Abschnitt Vorheriges Verhalten zurückgegeben wurde, auch wenn sie falsch waren, sollten Sie Ihren Code jetzt so aktualisieren, dass die Werte im Abschnitt Neues Verhalten erwartet werden.
Wenn der Leistungsaufwand für das neue Verhalten für Ihr Szenario nicht angemessen ist, können Sie die neuen schnellen ConvertToIntegerNative<TInteger>
Methoden für Einfach, Doppelt und Halb verwenden. In den meisten Fällen entspricht das Verhalten dieser Methoden dem vorherigen Verhalten bei der Konvertierung von Gleitkomma in Ganzzahlwerte. Diese Methoden weisen jedoch ein plattformspezifisches Verhalten auf, für das keine Übereinstimmung mit dem vorherigen Konvertierungsverhalten garantiert werden kann (das bereits nicht deterministisch war). Diese Methoden führen stattdessen die Aktion aus, die für die native Plattform am effizientesten ist. Das Ergebnis kann insbesondere für Werte, die außerhalb des darstellbaren Bereichs des TInteger
-Typs liegen, nicht garantiert werden.
In dem ungewöhnlichen Fall, dass Sie sowohl Leistung als auch eine strenge Garantie für die Übereinstimmung mit dem vorherigen Konvertierungsverhalten benötigen, können Sie die plattformspezifischen intrinsischen Hardwarefunktionen verwenden. Sie können beispielsweise Sse.ConvertToInt32(Vector128.CreateScalar(val)) verwenden, um (int)val
für float
zu verarbeiten. Sie müssen vor der Verwendung if (Sse.IsSupported)
heranziehen. Die Verwendung dieser intrinsischen Funktionen ist jedoch nicht einfach, da unterschiedliche Zielplattformen (z. B. Arm64) abweichende Ergebnisse erzeugen.
Betroffene APIs
Alle expliziten und impliziten Konvertierungen vom Gleitkomma- in Ganzzahlwerte:
(int)val
, wobeival
float
oderdouble
istVector.ConvertToInt32(Vector<float> val)
(long)val
, wobeival
float
oderdouble
istVector.ConvertToInt64(Vector<double> val)
(uint)val
, wobeival
float
oderdouble
istVector.ConvertToUInt32(Vector<float> val)
(ulong)val
, wobeival
float
oderdouble
istVector.ConvertToUInt64(Vector<double> val)