Reputation: 171
The string value is "90-"
. Why does the decimal parse it as "-90"
but double
throws a FormatException
?
var inputValue= "90-";
Console.WriteLine(decimal.Parse(inputValue));
Console.WriteLine(double.Parse(inputValue));
Upvotes: 17
Views: 1380
Reputation: 152511
The implementation is different between the two:
public static double Parse(String s) {
return Parse(s, NumberStyles.Float| NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
}
public static Decimal Parse(String s) {
return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo);
}
where
NumberStyles.Float = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
AllowDecimalPoint | AllowExponent,
NumberStyles.Number = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
AllowDecimalPoint | AllowThousands
So decimal.Parse
allows trailing signs but double.Parse
does not.
Looks like the documentation on MSDN is inaccurate:
Parameter s contains a number of the form:
[ws][sign][digits,]digits[.fractional-digits][ws]
It should indicate that a trailing sign is valid as well.
Upvotes: 8
Reputation: 45135
Interesting, it seems that by default, decimal
and double
use different number styles:
http://msdn.microsoft.com/en-us/library/cafs243z.aspx
Parameter s is interpreted using the NumberStyles.Number style. This means that white space and thousands separators are allowed but currency symbols are not.
http://msdn.microsoft.com/en-us/library/fd84bdyt(v=vs.110).aspx
The s parameter is interpreted using a combination of the NumberStyles.Float and NumberStyles.AllowThousands flags. This means that white space and thousands separators are allowed, for example, while currency symbols are not.
It's not immediately obvious from those descriptions, but if you look it up, NumberStyles.Number
allows trailing sign:
http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx
Indicates that the AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, and AllowThousands styles are used. This is a composite number style.
Presumably the difference in the defaults is because decimal
is often used for currency calculations.
Of course, in both cases you can supply your own number format specifying exactly what you do and don't want to accept so you can make them consistent for your own use.
Upvotes: 4
Reputation: 31393
The decimal.Parse(string s)
overload, by default, is called with NumberStyle NumberStyles.Number
which is defined as:
Indicates that the AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, and AllowThousands styles are used. This is a composite number style.
Note that AllowTrailingSign
is included. If you wish to customize the behaviour then you should explicitly call the overload that allows you to specify a number style and tailor it to your needs.
Upvotes: 15