我需要将字符串“1.2345E-02”(以指数表示法表示的数字)解析为十进制数据类型,但Decimal.Parse("1.2345E-02")
只是抛出错误
10 回答
这是一个浮点数,你必须告诉它:
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
,它使用 AllowLeadingWhite、AllowTrailingWhite、AllowLeadingSign、AllowTrailingSign、AllowDecimalPoint 和 AllowThousands 样式。可能与性能有关;我想,指定指数是比较少见的。
除了指定 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);
的默认NumberStyle
值为,因此如果您只想添加允许指数的功能,那么您可以执行按位 OR 来包含。decimal.Parse(String)
NumberStyles.Number
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
我建议使用 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);
关于使用 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);
}
希望这可以帮助某人。