我需要将用指数表示法表示的字符串“1.2345E-02”(一个数字)解析为十进制数据类型,但是Decimal.Parse("1.2345E-02")
会抛出错误。
我需要将用指数表示法表示的字符串“1.2345E-02”(一个数字)解析为十进制数据类型,但是Decimal.Parse("1.2345E-02")
会抛出错误。
它是一个浮点数,你必须告诉它:
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
如果您指定NumberStyles.Float
,它就能正常工作:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float);
Console.WriteLine(x); // Prints 0.012345
我并不确定为什么默认情况下不支持指数形式 - 默认情况下使用的是NumberStyles.Number
,它使用了允许前导空格、允许尾随空格、允许前导符号、允许尾随符号、允许小数点和允许千位数分隔符等样式。可能这与性能有关;我想指定指数形式是相对较少的。
除了指定NumberStyles外,我建议您使用decimal.TryParse函数,例如:
decimal result;
if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) )
{
// do something in case it fails?
}
如果你确定格式的话,可以使用特定的集合来代替NumberStyles.Any。例如:
NumberStyles.AllowExponent | NumberStyles.Float
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
对所选答案要谨慎:在Decimal.Parse中有一个微妙之处,指定了System.Globalization.NumberStyles.Float,这可能会导致System.FormatException,因为您的系统可能正在等待用“,”而不是“.”格式化的数字。
例如,在法国的表示法中,“1.2345E-02”是无效的,您必须首先将其转换为“1,2345E-02”。
总之,请使用以下类似内容:
Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);
在使用 decimal.Parse(String)
方法时,其默认的 NumberStyle
是 NumberStyles.Number
,所以如果你只想添加允许指数的功能,那么可以使用位运算符 OR 来包含 NumberStyles.AllowExponent
。
decimal d = decimal
.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
NumberStyles.Float
会改变字符串处理的规则,并导致与NumberStyles.Number
(由decimal.Parse
使用的默认规则)不同的输出结果。FormatException
:CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5", NumberStyles.Float, culture); // FormatException thrown here
NumberStyles.Number | NumberStyles.AllowExponent
,因为这样可以允许指数形式的数字,并且仍然可以按照 decimal
规则处理字符串。CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5",NumberStyles.Number | NumberStyles.AllowExponent, culture); // Does not generate a FormatException
回答发帖者的问题,正确的答案应该是:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
Console.WriteLine(x);
关于使用NumberStyles.Any的警告:
"6.33E+03"按预期转换为6330。在德国,小数点用逗号表示,但是6,33E+03转换为633000!这对我的客户是一个问题,因为生成数据的文化并不知道,可能与操作数据的文化不同。在我的情况下,我总是有科学计数法,所以我可以在解析之前始终将逗号替换为小数点,但是如果您正在处理任意数字,例如格式漂亮的数字,如1,234,567,则该方法无效。
您不需要替换点(或逗号),只需指定输入的 IFormatProvider:
float d = Single.Parse("1.27315", System.Globalization.NumberStyles.Float, new CultureInfo("en-US"));
float d = Single.Parse("1,27315", System.Globalization.NumberStyles.Float, new CultureInfo("de-DE"));
string val = "1.2345E-02";
double dummy;
bool hasExponential = (val.Contains("E") || val.Contains("e")) && double.TryParse(val, out dummy);
if (hasExponential)
{
decimal d = decimal.Parse(val, NumberStyles.Float);
}
希望这能帮助到某个人。
double
替换decimal
对我来说很好用,就像我预期的那样。如果你能提供你正在尝试做什么、你正在使用的代码和结果的详细信息,那么帮助你将会更容易。 - Jon Skeet