106

我需要将字符串“1.2345E-02”(以指数表示法表示的数字)解析为十进制数据类型,但Decimal.Parse("1.2345E-02")只是抛出错误

4

10 回答 10

197

这是一个浮点数,你必须告诉它:

decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
于 2010-10-07T07:22:21.470 回答
54

如果您指定它可以工作NumberStyles.Float

decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float);
Console.WriteLine(x); // Prints 0.012345

我不完全确定为什么默认情况下不支持此功能 - 默认情况下使用NumberStyles.Number,它使用 AllowLeadingWhite、AllowTrailingWhite、AllowLeadingSign、AllowTrailingSign、AllowDecimalPoint 和 AllowThousands 样式。可能与性能有关;我想,指定指数是比较少见的。

于 2010-10-07T07:23:50.883 回答
36

除了指定 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
于 2012-02-27T12:17:29.183 回答
15
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
于 2010-10-07T07:24:36.117 回答
11

请谨慎选择答案:在Decimal.Parse中有一个指定System.Globalization.NumberStyles.Float的微妙之处,这可能会导致System.FormatException,因为您的系统可能正在等待格式为“,”而不是“。”的数字。

例如,在法语符号中,“1.2345E-02”是无效的,您必须先将其转换为“1,2345E-02”。

总之,使用以下内容:

Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);
于 2016-11-21T11:11:20.290 回答
6

的默认NumberStyle值为,因此如果您只想添加允许指数的功能,那么您可以执行按位 OR 来包含。decimal.Parse(String)NumberStyles.NumberNumberStyles.AllowExponent

decimal d = decimal
    .Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
于 2021-01-06T17:02:08.860 回答
4

我发现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

我建议使用 input 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);
于 2017-03-09T17:50:28.590 回答
1

关于使用 NumberStyles.Any 的警告:

“6.33E+03”按预期转换为 6330。在德语中,小数点用逗号表示,但 6,33E+03 转换为 633000!这对我的客户来说是个问题,因为生成数据的文化是未知的,并且可能与对数据进行操作的文化不同。就我而言,我总是有科学记数法,所以我总是可以在解析之前将逗号替换为小数点,但如果你使用的是任意数字,比如像 1,234,567 这样的格式漂亮的数字,那么这种方法就行不通了。

于 2015-12-18T23:48:25.343 回答
0

您不需要替换点(分别是逗号),只需指定输入 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"));
于 2019-06-26T12:55:12.613 回答
0

如果要检查并转换指数值,请使用此

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

希望这可以帮助某人。

于 2019-07-31T06:00:43.070 回答