float 是否可以通过 double 往返而不损失精度?
Can float be round tripped via double without losing precision?
如果我有一个 C# float
,我可以将它转换为 double
而不会丢失任何精度吗?
如果 double
转换回 float
,它的值是否完全相同?
让我们用代码来测试一下:
[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,然后再返回不会丢失任何信息。
是的。 IEEE754 浮点数(这是 C# 必须使用的)保证:
将 float
转换为 double
会完全 保留相同的值
将 double
转换回 float
可以恢复 原来的 float
。
double
的集合是 float
的超集。
请注意,此 也 适用于 NaN
、+Infinity
和 -Infinity
。零的符号也被保留。
如果我有一个 C# float
,我可以将它转换为 double
而不会丢失任何精度吗?
如果 double
转换回 float
,它的值是否完全相同?
让我们用代码来测试一下:
[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,然后再返回不会丢失任何信息。
是的。 IEEE754 浮点数(这是 C# 必须使用的)保证:
将
float
转换为double
会完全 保留相同的值将
double
转换回float
可以恢复 原来的float
。
double
的集合是 float
的超集。
请注意,此 也 适用于 NaN
、+Infinity
和 -Infinity
。零的符号也被保留。