为什么float.ToString(“F15”)虽然有足够的数字但是精度下降了?

时间:2018-01-30 13:21:01

标签: .net floating-point

我认为float.ToString("F15")有足够的数字可以不降低精度,但确实会降低精度:

float f = 0.105700679f;
Console.WriteLine(f == 0.105700679f); //True
Console.WriteLine(f == 0.1057007f); //False
Console.WriteLine(f.ToString("F15")); //0.105700700000000
Console.WriteLine(f.ToString("R")); //Round-trip format: 0.105700679

即使有足够的数字可用于精确表示该值,F格式似乎也不能对同一值进行循环转换。我在.NET 4.7.1上运行它。有人可以对此有所了解吗?这是一个错误吗?

不幸的是,不同的浮点值会转换为相同的字符串:

float f1 = 0.105700657f;
float f2 = 0.105700679f;

Console.WriteLine(f1.ToString("F15")); //0.105700700000000
Console.WriteLine(f2.ToString("F15")); //0.105700700000000

您可以使用https://www.h-schmidt.net/FloatConverter/IEEE754.html确认这些浮点常量确实是不同的IEEE浮点值。所以这不仅仅是编译时精度的损失。

1 个答案:

答案 0 :(得分:2)

这可能是由于"R" standard format string中浮点类型的已知限制(错误?):

  

对于DoubleSingle值," R"在某些情况下,格式说明符无法成功地往返原始值,并且性能相对较差。相反,我们建议您使用" G17" Double值的格式说明符和" G9"格式说明符成功地往返Single值。

我还要注意,十进制只能保证7位数的精度,所以你显示的结果并不是完全出乎意料的(f1f2都给出了7位精度的相同数字。