2016-11-11 38 views

Odpowiedz

8

Tak. IEEE754 zmiennoprzecinkowa (czego C# musi używać) gwarantuje to:

  1. Konwersja float Do double zachowuje dokładnie sama wartość

  2. Konwersja że double z powrotem do float odzyskuje dokładnie ten oryginalny float.

Zestaw double S jest rozszerzeniem float s.

Zauważ, że ten również dotyczy NaN, +Infinity i -Infinity. Zachowana jest także wartość zero.

6

zróbmy to z kodem:

[Fact] 
public void IsFloatRoundTrippableToDouble() 
{ 
    var bits = default(FloatUnion); 
    bits.FloatData = float.MinValue; 

    var testBits = default(FloatUnion); 

    // ReSharper disable once LoopVariableIsNeverChangedInsideLoop 
    while (bits.FloatData <= float.MaxValue) 
    { 
     var d = (double)bits.FloatData; 
     testBits.FloatData = (float)d; 

     if (bits.IntData != testBits.IntData) 
      Assert.True(false); 

     bits.IntData -= 1; 
    } 
} 

[StructLayout(LayoutKind.Explicit)] 
private struct FloatUnion 
{ 
    [FieldOffset(0)] public uint IntData; 
    [FieldOffset(0)] public float FloatData; 
} 

Ten kod testuje każdą wartość float między MinValue i MaxValue (oprócz NaN, nieskończoności, etc ...). Reprezentacja bajtów w pamięci jest porównywana, aby upewnić się, że nie ma żadnych innych konwersji.

Chociaż może wydawać się szalonym przetestować ~ 4 miliardy możliwych liczb zmiennoprzecinkowych, to faktycznie działa w ciągu około 11 sekund na moim komputerze.

I tak, konwersja jest bezpieczna. Konwersja z poziomu zmiennoprzecinkowego, podwójna, a następnie z powrotem nie powoduje utraty żadnych informacji.

+1

Nie jestem pewien, dlaczego to opublikowałeś, czy nie byłoby to bardziej odpowiednie w dokumentacji? –

+2

Nie zgadzam się. To wciąż dobre pytanie i odpowiedź. Nie ma nic złego w odpowiadaniu na twoje własne pytanie. – Bathsheba