Casting double.NaN na int bude 0.
Console.WriteLine(unchecked((int)double.NaN)); // 0
Priradenie premennej double.NaN a následné odovzdanie na int však bude -2147483648.
double value = double.NaN;
Console.WriteLine (unchecked ((int) value)); // -2147483648
Console.WriteLine ((int) value); // -2147483648
Prečo sa výsledok mení v závislosti od toho, či ho priradíte k premennej alebo nie?
Špecifikácia C #
6.2.1 Explicitné číselné prevody
- V kontrolovanom kontexte konverzia prebieha takto:
- Ak je hodnota operandu NaN alebo nekonečná, vyvolá sa System.OverflowException.
- V opačnom prípade je zdrojový operand zaokrúhlený na nulu na najbližšiu celkovú hodnotu. Ak je táto integrálna hodnota v rozsahu cieľového typu, potom je táto hodnota výsledkom prevodu.
- V opačnom prípade sa vyvolá System.OverflowException.
- V nekontrolovanom kontexte je konverzia vždy úspešná a prebieha nasledovne.
- Ak je hodnota operandu NaN alebo nekonečná, výsledkom prevodu je nešpecifikovaná hodnota typu cieľa.
- V opačnom prípade je zdrojový operand zaokrúhlený na nulu na najbližšiu celkovú hodnotu. Ak je táto integrálna hodnota v rozsahu cieľového typu, potom je táto hodnota výsledkom prevodu.
- V opačnom prípade je výsledkom prevodu nešpecifikovaná hodnota typu cieľa.
envrionment
- Kompilátor: Visual Studio 2013
- Rimtime: .NET Framework 4.6.0
- OS: Windows 10 verzia 1607
- CPU: Intel Core i7 920
Windows:
Console.WriteLine(Environment.OSVersion); // Microsoft Windows NT 6.2.9200.0
Console.WriteLine(Environment.Version); // 4.0.30319.42000
odpovede:
3 pre odpoveď č. 1Predvolene je konzolová aplikácia kompilovaná ako unchecked
. Váš posledný príklad preto ukazuje rovnakú hodnotu ako výslovne uvedené príklady unchecked
.
Pre ostatné vaše príklady platí časť s technickými údajmi, ktorú ste uviedli:
- V nekontrolovanom kontexte je konverzia vždy úspešná a prebieha nasledovne.
- Ak je hodnota operandu NaN alebo nekonečná, výsledkom prepočtu je nešpecifikovaná hodnota typu destinácie.
(zdôraznil mnou).
nešpecifikované znamená, že sa nemôžete spoliehať na výsledok. To môže byť 0
alebo -2147483648
alebo čokoľvek iného.
Chcel by som zistiť, čo sa vo vašom špeciálnom prípade stane pod kapotou, ale chápem -2147483648
pre oba spôsoby. Je teda ťažké vypátrať.
1 pre odpoveď č. 2
Po trochu rozhliadnutí sa domnievam, že tu vidím, čo sa deje. Nehodíte 0, castujete NaN. int
, alebo Int32
má oveľa menší rozsah ako double
, ja premýšľať tieto príjemne nie celkom jasné pravidlá spolupracujú na tom, aby spôsobili rozdiel:
- Ak je hodnota operandu NaN alebo nekonečná,výsledkom prevodu je nešpecifikovaná hodnota typu cieľa. V opačnom prípade je zdrojový operand zaokrúhlený na nulu na najbližšiu celkovú hodnotu.
- Ak je táto integrálna hodnota v rozsahu cieľového typu, potom je táto hodnota výsledkom prevodu.
Typ cieľa je tu menší int
a hodnota „-2147483648“, ktorú získavate, je minimálna hodnota 32-bitového celého čísla so znamienkom. To naznačuje, že operácia odlievania prevádza NaN na double.NegativeInfinity
za účelom vykonania operácie s ním. Najbližšie celé číslo do double.NegativeInfinity
je int.MinValue
, čo je hodnota, ktorú získavate.
Všetko toto hovorilo, skutočnosť, že táto hodnota je NS znamená, že závisí aj od výsledku, ktorý získateveľa faktorov, až po to, či ste priradili premennú alebo nie, alebo dokonca akú architektúru procesora máte. „Nemali by ste používať casting NaN na nič zmysluplné, takže NaN nikdy nie je priradená skutočná nastavená hodnota (hlavne preto, že by to bolo, samozrejme, číslo). S výsledkom NaN by sa malo vo väčšine prípadov zaobchádzať ako s chyba z tohto dôvodu. Skutočná hodnota je nakoniec nezmyselná.