Scott Hanselman

Why you can't Double.Parse(Double.MaxValue.ToString()) or System.OverloadExceptions when using Double.Parse

January 18, 2005 Comment on this post [4] Posted in Web Services | XML
Sponsored By

This was an interesting one. A fellow here was returning double.MaxValue in an XML element and was seeing:

System.InvalidOperationException : There is an error in XML document (1, 539).----> System.OverflowException : Value was either too large or too small for a Double.

It seems that while he was sending out Double.MaxValue the system was unable to use Double.Parse() on it. In other words, he wasn't able to "roundtrip" his value, like Double.Parse(Double.MaxValue.ToString()).

The problem stems from there being no 1:1 representation between decimal and floating point numbers. For example, how do you express 2/3? Do you say 0.6666666667? You've rounded up. You can't say 0.66666 with that little bar on the top. So, you either have to round up (creating data) or limit the digits (losing data). 

//This will throw a System.OverflowException…
double d1 = double.Parse( "1.79769313486232E+308" );

Change the last digit:

double d2 = double.Parse( "1.79769313486231E+308" );
//This will work.

A few interesting articles I found referenced in Google Groups:

INFO: Precision and Accuracy in Floating-Point Calculations: Q125056
INFO: IEEE Floating-Point Representation and MS Languages: Q36068


Using Edge Cases as Magic Numbers is more evil than using Magic Numbers


However, you can use Double.MaxValue.ToString("R") to prefer roundtrips over precision. From the MSDN Help:

The round-trip specifier guarantees that a numeric value converted to a string will be parsed back into the same numeric value. When a numeric value is formatted using this specifier, it is first tested using the general format, with 15 spaces of precision for a Double and 7 spaces of precision for a Single. If the value is successfully parsed back to the same numeric value, it is formatted using the general format specifier. However, if the value is not successfully parsed back to the same numeric value, then the value is formatted using 17 digits of precision for a Double and 9 digits of precision for a Single. Although a precision specifier can be appended to the round-trip format specifier, it is ignored. Round trips are given precedence over precision when using this specifier. This format is supported by floating-point types only.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
January 18, 2005 2:10
Very interesting. I never would have thought about the problems faced by using such classification of a number. I better go back and make sure I'm not trying to use a MinValue or MaxValue as a magic number.

On a side note, it looks like you have a typo in second paragraph: "was enable" where it should be "was unable".
January 18, 2005 20:09
I recently came to that same semi-conclusion. I was using DateTime.MinValue to represent the "null" date. The DateTimePicker control I was using didn't like that at all.

So, if I can't use the edge case as a magic number, how do I represent a missing date (before .NET 2.0)? I suppose I can implement my own nullable structure...
January 19, 2005 1:58
I found that one when assigning Double.Max to a RangeValidator to (lazily I admit) validate a double. In the process I found out that the RangeValidator uses a hard coded regular expression that doesn't understand scientific notation... for details.
August 26, 2005 23:05
Thanks for the page. I just had this happen in an nUnit test where a double.MaxValue.ToString() bit me in an XML conversion process. The ToString("R") did the trick.

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.