C# decimal.Parse behaviour
Short question:
Why are these '.....' valid for parsing a decimal in .NET (C#):
decimal res = decimal.Parse("8......15"); // returns 815
decimal res = decimal.Parse("8...15"); // returns 815
decimal res = decimal.Parse("8..15"); // returns 815
What's the开发者_如何学编程 reason for this?
It fails for me. Are you by any chance in a culture where "." is the thousands separator and "," is the decimal point? Decimal.Parse
(and similar calls) use the thread's current culture by default. Whether that is a good thing or not is debatable, but irrelevant to actual behaviour :)
Try specifying CultureInfo.InvariantCulture
in the decimal.Parse
call:
decimal res = decimal.Parse("8......15", CultureInfo.InvariantCulture);
I believe that will behave as you expected.
I would imagine it's because the parser doesn't actually care about group separators - they are irrelevant to the process of converting a string to a decimal.
We call them thousands separators, but they're really not. They are group separators - you could split every 3 digits, every 10 digits, every 1 digit, so why not every 0 digits?
Interestingly, the code has changed for .NET 4 - this is the relevant output from Reflector for me:
else
{
if (((currencySymbol == null) ||
((chPtr2 = MatchChars(p, currencySymbol)) == null)) &&
((ansiCurrencySymbol == null) ||
((chPtr2 = MatchChars(p, ansiCurrencySymbol)) == null)))
{
break;
}
num |= 0x20;
currencySymbol = null;
ansiCurrencySymbol = null;
p = chPtr2 - 1;
}
I don’t know why, but I know how it works (decimal parser code part see below). I think last else if just turn on point flag and skip all points.
while (true)
{
if (((ch >= '0') && (ch <= '9')) || (((options & NumberStyles.AllowHexSpecifier) != NumberStyles.None) && (((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F')))))
{
//Here goes some code...
}
else if ((((options & NumberStyles.AllowDecimalPoint) != NumberStyles.None) && ((num & 0x10) == 0))
&& (((chPtr2 = MatchChars(p, currencyDecimalSeparator)) != null) || ((flag && ((num & 0x20) == 0))
&& ((chPtr2 = MatchChars(p, numberDecimalSeparator)) != null))))
{
num |= 0x10;
p = chPtr2 - 1;
}
}
Use Reflector tool to investigate all code.
精彩评论