转换浮点数 - >双 - >浮动

时间:2015-04-15 10:50:43

标签: c# floating-point

是否可以将float转换为double,然后返回而不会丢失精度?我的意思是第一个浮点数应该与结果浮点数一样一点一点。

2 个答案:

答案 0 :(得分:5)

是的,我们可以测试一下:

float fl = float.NegativeInfinity;

long cycles = 0;

while (true)
{
    double dbl = fl;
    float fl2 = (float)dbl;

    int flToInt1 = new Ieee754.Int32SingleConverter { Single = fl }.Int32;
    int flToInt2 = new Ieee754.Int32SingleConverter { Single = fl2 }.Int32;

    if (flToInt1 != flToInt2)
    {
        Console.WriteLine("\nDifferent: {0} (Int32: {1}, {2})", fl, flToInt1, flToInt2);
    }

    if (fl == 0)
    {
        Console.WriteLine("\n0, Sign: {0}", flToInt1 < 0 ? "-" : "+");
    }

    if (fl == float.PositiveInfinity)
    {
        fl = float.NaN;
    }
    else if (float.IsNaN(fl))
    {
        break;
    }
    else
    {
        fl = Ieee754.NextSingle(fl);
    }

    cycles++;

    if (cycles % 100000000 == 0)
    {
        Console.Write(".");
    }
}

Console.WriteLine("\nDone");
Console.ReadKey();

和实用程序类:

public static class Ieee754
{
    [StructLayout(LayoutKind.Explicit)]
    public struct Int32SingleConverter
    {
        [FieldOffset(0)]
        public int Int32;

        [FieldOffset(0)]
        public float Single;
    }

    public static float NextSingle(float value)
    {
        int bits = new Int32SingleConverter { Single = value }.Int32;

        if (bits >= 0)
        {
            bits++;
        }
        else if (bits != int.MinValue)
        {
            bits--;
        }
        else
        {
            bits = 0;
        }

        return new Int32SingleConverter { Int32 = bits }.Single;
    }
}

在我的计算机上,在发布模式下,没有调试器(来自Visual Studio的Ctrl + F5),大约需要2分钟。

大约有40亿个不同的float值。我把它们转换成int转换为二进制检查它们。请注意NaN值是&#34;特殊&#34;。 IEEE754标准有NaN的多个值,但.NET&#34;压缩&#34;它们是一个NaN值。因此,您可以创建一个NaN值(手动,通过位操作),不会正确地来回转换。 &#34;标准&#34; NaN值已正确转换,PositiveInfinityNegativeInfinity+0-0也是如此。

答案 1 :(得分:0)

是的,因为每个浮点数都可以精确地表示为一个双精度数,所以往返将为您提供您开始使用的确切值。

您的要求有一个可能的技术例外,它们是逐位相同的:有多个位模式对应于NaN值(这通常被称为&#34; NaN有效载荷&#34; )。据我所知,没有严格的要求保留这个:你仍然会得到一个NaN,可能只是略有不同。