可以通过双重浮动而不会丢失精度吗?

时间:2016-11-11 15:12:57

标签: c# .net floating-point precision floating-point-conversion

如果我有C#float,我可以将其转换为double而不会失去任何精度吗?

如果将double转换回float,它是否会具有完全相同的值?

2 个答案:

答案 0 :(得分:8)

是。 IEEE754浮点(这是C#必须使用的)保证了这一点:

  1. float转换为double保留完全相同的值

  2. double转换回float可以完全恢复原始float

  3. double s的集合是float s的超集。

    请注意,此 也适用于NaN+Infinity-Infinity。零的签名也得以保留。

答案 1 :(得分: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;
}

此代码测试floatMinValue之间的每个MaxValue值(NaN除外,无穷大等...)。比较内存中的字节表示,以确保不会发生其他转换。

虽然测试大约40亿个可能的浮点数似乎很疯狂,但它实际上在我的机器上运行了大约11秒。

是的,转换是安全的。从浮动转换为双倍,然后再转回,不会丢失任何信息。