Převody s plovoucí desetinou čárkou na celé číslo jsou nasycené
Převody s plovoucí desetinou čárkou na celé číslo teď mají na počítačích x86 a x64 sytoucí chování. Sytácí chování znamená, že pokud je převedená hodnota pro cílový typ příliš malá nebo velká, nastaví se hodnota na minimální nebo maximální hodnotu daného typu.
Předchozí chování
Následující tabulka ukazuje předchozí chování při převodu float
hodnoty nebo double
hodnoty.
Převést na ... | Hodnota x |
(Předchozí) výsledek |
---|---|---|
int skalární a zabalené |
int.MinValue <= x <= int.MaxValue |
(int)x |
< int.MinValue nebo > int.MaxValue |
int.MinValue |
|
long skalární a zabalené |
long.MinValue <= x <= long.MaxValue |
(long)x |
< long.MinValue nebo > long.MaxValue |
long.MinValue |
|
uint skalární a zabalené |
Libovolná hodnota | (((long)x << 32) >> 32) |
ulong skalární a zabalené |
<= 2^63 |
(long)x |
> 2^63 |
(long)(x - 2^63) + 2^63 |
Nové chování
Následující tabulka ukazuje nové chování při převodu float
hodnoty nebo hodnoty double
.
Převést na ... | Hodnota x |
Výsledek .NET 9+ |
---|---|---|
int skalární a zabalené |
int.MinValue <= x <= int.MaxValue |
(int)x |
< int.MinValue |
int.MinValue |
|
> int.MaxValue |
int.MaxValue |
|
NaN |
0 | |
long skalární a zabalené |
long.MinValue <= x <= long.MaxValue |
(long)x |
< long.MinValue |
long.MinValue |
|
> long.MaxValue |
long.MaxValue |
|
NaN |
0 | |
uint skalární a zabalené |
0 <= x <= uint.MaxValue |
(uint)x |
x > uint.MaxValue |
uint.MaxValue |
|
x < 0 |
0 | |
ulong skalární a zabalené |
0 <= x <= ulong.MaxValue |
(ulong)x |
x > ulong.MaxValue |
ulong.MaxValue |
|
x < 0 |
0 |
Zavedená verze
.NET 9 Preview 4
Typ zásadní změny
Tato změna je změna chování.
Důvod změny
Tato změna byla provedena tak, aby standardizovala všechny převody s plovoucí desetinnou čárkou na celé číslo, aby měly nasycené chování a aby chování bylo deterministické.
Doporučená akce
Pokud jste se spoléhali na hodnoty uvedené v části Předchozí chování , které se mají vrátit z převodu, i když byly nesprávné, aktualizujte kód tak, aby očekával hodnoty uvedené v části Nové chování .
Pokud je pro váš scénář nežádoucí režie na výkon nového chování, můžete místo toho použít nové ConvertToIntegerNative<TInteger>
metody single, Double a Half, které jsou rychlé. Ve většině případů chování těchto metod odpovídá předchozímu chování převodu s plovoucí deseti čárkou na celé číslo. Tyto metody však mají chování specifické pro platformu, které není zaručeno, že odpovídá předchozímu chování při převodu (které již nebylo deterministické). Místo toho tyto metody dělají co nejefektivnější pro nativní platformu. Zejména výsledek není zaručen pro hodnoty, které jsou mimo reprezentovatelný rozsah TInteger
typu.
V neobvyklém případě, kdy potřebujete výkon a striktní záruku odpovídající předchozímu chování při převodu, můžete použít vnitřní funkce hardwaru specifické pro platformu. Můžete například použít Sse.ConvertToInt32(Vector128.CreateScalar(val)) pro zpracování (int)val
float
. Před použitím musíte zkontrolovat if (Sse.IsSupported)
. Použití těchto vnitřních objektů je ale složité, protože jiné cílové platformy (například Arm64) již produkují různé výsledky.
Ovlivněná rozhraní API
Všechna explicitní a implicitní přetypování z plovoucí desetiny na celé číslo:
(int)val
kdeval
je nebofloat
double
Vector.ConvertToInt32(Vector<float> val)
(long)val
kdeval
je nebofloat
double
Vector.ConvertToInt64(Vector<double> val)
(uint)val
kdeval
je nebofloat
double
Vector.ConvertToUInt32(Vector<float> val)
(ulong)val
kdeval
je nebofloat
double
Vector.ConvertToUInt64(Vector<double> val)