2016-11-11 13 views

ответ

8

Да. IEEE754 плавающей точкой (что C# должны использовать) гарантирует следующее:

  1. Преобразование float к double сохраняет точно же значение

  2. Преобразование, что double назад к float восстанавливает точно это оригинал float.

Множество double с является подмножеством float с.

Обратите внимание, что это также относится к NaN, +Infinity и -Infinity. Подписанность нуля также сохраняется.

6

Давайте это с кодом:

[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; 
} 

Этот код проверяет каждую float значение между MinValue и MaxValue (кроме NaN, бесконечностей, и т.д. ...). Представление байтов в памяти сравнивается, чтобы обеспечить отсутствие других преобразований.

Хотя может показаться сумасшедшим, чтобы проверить число возможных чисел с плавающей запятой размером ~ 4 миллиарда, оно фактически работает примерно на 11 секунд на моей машине.

И да, преобразование безопасно. Преобразование из float, двойное, а затем обратно не потеряет никакой информации.

+1

Я в замешательстве, почему вы разместили это, не было бы более уместным в документации? –

+2

Я не согласен. Это все еще хороший вопрос и ответ. Нет никакого вреда в ответе на ваш собственный вопрос. – Bathsheba