32

Please see my example below.

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?
3
  • 17
    Dmitry has the answer, but note that comparing floats for exact equality is almost always a mistake - you should pick the kind of precision you want, make sure it's within the capabilities of the given data type, and do the comparison only to the given precision. Commented Nov 23, 2015 at 9:56
  • 16
    @Luaan It is not a mistake if you're making sure that round-trips do not change the value, which is a valid thing to want from your serialization and deserialization. Even if later calculations are not exactly predictable because of rounding, there is no reason to accept rounding error on steps that can be exact (such as a float -> string -> float roundtrip). Commented Nov 23, 2015 at 12:59
  • 2
    Comparing floating-point values for equality is almost always a bug. Commented Nov 23, 2015 at 23:35

2 Answers 2

47

You should use "R" format string:

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" or "r" Round-trip Result: A string that can round-trip to an identical number. Supported by: Single, Double, and BigInteger. Precision specifier: Ignored.

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

  bool mustEqual = (maxFloat == result);
Sign up to request clarification or add additional context in comments.

2 Comments

Hang on, doesn't that mean it isn't officially supported by float?
@deworde: float and Single are synonyms: msdn.microsoft.com/en-US/library/b1e65aza.aspx (as well as double and Double). "Type float ... .NET Framework type System.Single"
29

// It returns FALSE, why?

Because float.ToString() outputs a 7-digit precision number by default, so your float.MaxValue which has a value of 3.40282347E+38 (9-digit precision) will become rounded to 3.402823E+38 and your check fails because of course 3.402823E+38 != 3.40282347E+38.

If you explicitly specify a format specifier to output float.MaxValue with 9-digit precision, e.g. float.MaxValue.ToString("G9"), your check will succeed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.