十进制分析问题

本文关键字:问题 十进制 | 更新日期: 2023-09-27 18:00:23

字符串值为"90-"。为什么十进制将其解析为"-90",而double抛出FormatException

var inputValue= "90-";
Console.WriteLine(decimal.Parse(inputValue));
Console.WriteLine(double.Parse(inputValue));

十进制分析问题

默认情况下,使用NumberStyle NumberStyles.Number调用decimal.Parse(string s)重载,该重载定义为:

指示AllowLeadingWhite、AllowTrailingWhite,AllowLeadingSign、AllowTrailingSign、AllowDecimalPoint和使用AllowThousands样式。这是一种复合数字样式。

请注意,包含AllowTrailingSign。如果您希望自定义行为,那么您应该显式调用重载,该重载允许您指定数字样式并根据您的需要进行定制。

两者的实现不同:

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);
}

其中

NumberStyles.Float     = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | 
                         AllowDecimalPoint | AllowExponent,
NumberStyles.Number    = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
                         AllowDecimalPoint | AllowThousands

因此decimal.Parse允许尾随符号,但double.Parse不允许。

MSDN上的文档似乎不准确:

参数s包含一个数字形式:

[ws][sign][digits,]digits[.小数位数][ws]

它应该表明尾部的符号也是有效的。

有趣的是,默认情况下,decimaldouble使用不同的数字样式:

http://msdn.microsoft.com/en-us/library/cafs243z.aspx

参数s使用NumberStyles.Number样式进行解释。这意味着允许使用空格和数千个分隔符,但不允许使用货币符号。

http://msdn.microsoft.com/en-us/library/fd84bdyt(v=vs.110).aspx

s参数使用NumberStyles.Float和NumberStyls.AllowThousands标志的组合进行解释。例如,这意味着允许使用空格和数千个分隔符,而不允许使用货币符号。

从这些描述中并不能立即看出,但如果你查一下,NumberStyles.Number允许尾随符号:

http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx

指示使用AllowLeadingWhite、AllowTrailingWhite、alloLeadingSign、alloTrailingSign、AllowDecimalPoint和AllowThousands样式。这是一种复合数字样式。

默认值的差异可能是因为decimal经常用于货币计算。

当然,在这两种情况下,您都可以提供自己的数字格式,具体说明您要做什么和不想接受什么,这样您就可以使它们保持一致,供自己使用。