【问题标题】:Why is converting between string and float wrong?为什么在字符串和浮点数之间转换错误?
【发布时间】:2016-02-25 06:56:14
【问题描述】:

请看下面我的例子。

float maxFloat = float.MaxValue;
string s = maxFloat.ToString();
float result = float.Parse(s); // same with Convert.ToSingle(s);

bool mustEqual = (maxFloat == result);
// It returns FALSE, why?

【问题讨论】:

  • Dmitry 有答案,但请注意,比较浮点数是否完全相等几乎总是一个错误——您应该选择所需的精度,确保它在给定数据类型的能力范围内,并且只对给定的精度进行比较。
  • @Luaan 如果您确保往返不会更改值,这不是一个错误,这是您的序列化和反序列化所需的有效内容。即使以后的计算由于四舍五入而不能完全预测,也没有理由接受可能精确的步骤(例如浮点数 -> 字符串 -> 浮点数往返)的舍入误差。
  • 比较浮点值是否相等几乎是总是一个错误

标签: c# string floating-point


【解决方案1】:

你应该使用"R"格式字符串:

https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx.

https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#RFormatString

“R”或“r”往返结果:可以往返于 相同的号码。支持:Single、Double 和 BigInteger。 精度说明符:忽略。

  float maxFloat = float.MaxValue;
  string s = maxFloat.ToString("R"); // <- "R"
  float result = float.Parse(s);

  bool mustEqual = (maxFloat == result);

【讨论】:

  • 等等,这不是说它被float官方支持了吗?
  • @deworde: floatSingle 是同义词:msdn.microsoft.com/en-US/library/b1e65aza.aspx(以及 doubleDouble)。 "类型 float ... .NET Framework 类型 System.Single"
【解决方案2】:

// It returns FALSE, why?

因为 float.ToString() 默认输出一个 7 位精度的数字,所以您的 float.MaxValue 的值为 3.40282347E+38(9 位精度)将四舍五入为 3.402823E+38 并且您的检查当然会失败3.402823E+38 != 3.40282347E+38.

如果您明确指定格式说明符以 9 位精度输出 float.MaxValue,例如float.MaxValue.ToString("G9"),你的校验会成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 2011-11-25
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多