C# 转换浮动->;双->;浮动

C# 转换浮动->;双->;浮动,c#,floating-point,C#,Floating Point,是否可以将float转换为double,然后返回而不丢失精度?我的意思是,第一个浮点数应该与结果浮点数完全相同。是的,我们可以测试它: float fl = float.NegativeInfinity; long cycles = 0; while (true) { double dbl = fl; float fl2 = (float)dbl; int flToInt1 = new Ieee754.Int32SingleConverter { Single =

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

是的,我们可以测试它:

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();
在我的计算机上,在发布模式下,没有调试器(VisualStudio中的Ctrl+F5),大约需要2分钟


大约有40亿个不同的
float
值。我将它们转换为
int
以进行二进制检查。请注意,
NaN
值是“特定的”。IEEE754标准对
NaN
有多个值,但.NET将它们“压缩”为单个
NaN
值。因此,您可以创建一个不能正确来回转换的
NaN
值(手动,通过位操作)。“标准”
NaN
值转换正确,
PositiveInfinity
NegativeInfinity
+0
-0
是的,因为每个浮点值都可以精确地表示为双精度值,所以往返过程将给出您开始时的精确值


您的需求可能存在一个技术例外,即它们是逐位相同的:存在多个对应于NaN值的位模式(这通常被称为“NaN有效负载”)。据我所知,没有严格的要求保留这一点:你仍然会得到一个NaN,只是可能有一个稍有不同。

它们都有自己的精度,你可以将一个转换为另一个,但不是vice versaI想写这样的东西:)非常感谢。@zgnilec“有趣”的部分是如何找到浮点数之后的“下一个”浮点数。如果您想知道浮点数之间的“距离”(我已经有了
Ieee754
类…我在一年前试验Ieee754时编写了这个类),那么它会很有用
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;
    }
}