/ / Keď sa prenáša NaN na int, prečo sa hodnota mení v závislosti od toho, či je priradená k premennej alebo nie? - c #

Pri cast NaN na int, prečo sa hodnota mení v závislosti od toho, či je priradená premennej alebo nie? - c #

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ď č. 1

Predvolene 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ší inta 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á.