浮动可以通过双倍往返而不会丢失精度吗?
如果我有一个C# float
,我可以将它转换为double
而不会丢失任何精度吗?
如果该double
转换回float
,它是否具有完全相同的值?
是。 IEEE754浮点(这是C#必须使用的)保证了这一点:
-
将
float
转换为double
保留完全相同的值 -
将该
double
转换回float
恢复原始float
。
double
s的集合是float
s的超集。
请注意,这也适用于NaN
, +Infinity
和-Infinity
。 零的签名也被保留。
让我们用代码测试一下:
[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; }
此代码测试MinValue
和MaxValue
之间的每个float
值( NaN
,无穷大等除外)。 比较内存中的字节表示以确保不会发生其他转换。
虽然测试〜40亿个可能的浮点数似乎很疯狂,但它实际上在我的机器上运行大约11秒。
是的,转换是安全的。 从float转换为double,然后再转回,不会丢失任何信息。