简短的问题:
为什么这些' ..... '对于解析.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
这是什么原因?
答案 0 :(得分:19)
对我来说失败了。你是否有机会参加“。”文化。千位分隔符和“,”是小数点? Decimal.Parse
(和类似的调用)默认使用线程的当前文化。这是否是好事是值得商榷的,但与实际行为无关:)
尝试在CultureInfo.InvariantCulture
电话中指定decimal.Parse
:
decimal res = decimal.Parse("8......15", CultureInfo.InvariantCulture);
我相信这会表现得像你期望的那样。
答案 1 :(得分:2)
我认为这是因为解析器实际上并不关心组分隔符 - 它们与将字符串转换为小数的过程无关。
我们称他们为千位分隔符,但他们真的不是。它们是组分隔符 - 你可以每1位数,每10位数,每1位数,所以为什么不是每0位数?
有趣的是,代码已针对.NET 4进行了更改 - 这是我对Reflector的相关输出:
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;
}
答案 2 :(得分:1)
我不知道为什么,但我知道它是如何工作的(十进制解析器代码部分见下文)。如果只是打开点旗并跳过所有点,我想最后一点。
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;
}
}
使用反射器工具调查所有代码。