I have static method that takes a string for input and returns the original input string if the string represents a number. If the string does not represent a number the the input string is processed and a transformed string is returned. I'm writing test cases. I'm trying to verify that an input string containing either double.MinValue
or double.MaxValue
is returned unchanged. I've read through a number of forums, including StackOverflow, and have come up with the following logic:
string doubleMax = double.MaxValue.ToString();
double d;
CultureInfo cultureInfo = new CultureInfo("en-US", true);
if (Double.TryParse(doubleMax, NumberStyles.Any, cultureInfo.NumberFormat, out d))
{
Console.WriteLine("parsed");
}
else
{
Console.WriteLine("couldn't parse");
}
Problem is the Double.TryParse()
always returns false. I've called TryParse()
in a bunch of different ways, but the result is always the same, false.
This logic works if I use decimal.MinValue()
, int.MinValue()
, or float.MinValue()
.
Can someone tell me why my logic isn't working for double.MinValue
?
TryParse(String, Double) Converts the string representation of a number to its double-precision floating-point number equivalent. A return value indicates whether the conversion succeeded or failed.
TryParse is . NET C# method that allows you to try and parse a string into a specified type. It returns a boolean value indicating whether the conversion was successful or not. If conversion succeeded, the method will return true and the converted value will be assigned to the output parameter.
That's because of the way that floating point numbers are stored and displayed. The value is rounded when it's turned into a human readable string, and for double.MaxValue
it happens to be rounded up so that it no longer fits in a double
.
You can use the round-trip format "R" to turn a value into a string that always can be parsed back to the same value, as it adds extra precision until the correct value is returned. Also, use the same culture when formatting the number as parsing it, to avoid culture differences:
CultureInfo cultureInfo = new CultureInfo("en-US", true);
string doubleMax = Double.MaxValue.ToString("R", cultureInfo);
Console.WriteLine(doubleMax);
double d;
if (Double.TryParse(doubleMax, NumberStyles.Any, cultureInfo.NumberFormat, out d)) {
if (d == Double.MaxValue) {
Console.WriteLine("parsed");
} else {
Console.WriteLine("value changed");
}
} else {
Console.WriteLine("couldn't parse");
}
Output:
1.7976931348623157E+308
parsed
I added output of the string, and verification that the parsed value actually still is MaxValue.
There's nothing wrong with your logic, it's just a limitation i the Double.TryParse
API. From the documentation
Ordinarily, if you pass the Double.TryParse method a string that is created by calling the Double.ToString method, the original Double value is returned. However, because of a loss of precision, the values may not be equal. In addition, attempting to parse the string representation of either MinValue or MaxValue throws an OverflowException, as the following example illustrates.
The documentation appears to be taken from the Parse
method and applied to TryParse
since TryParse
does not throw. But the sample code following the pargraph uses TryParse
and expects it to fail for MaxValue
and MinValue
The problem is in the rounding of the ToString() method. The actual MaxValue according to the documentation is 1.7976931348623157E+308, but the ToString() of that gives you 1,79769313486232E+308, which is rounded up and thus too large to parse.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With