从指数表示法解析数字


85

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

Answers:


169

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

decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);

49

如果您指定,它将起作用NumberStyles.Float

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

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


我正在尝试使它与double一起工作,但似乎不会。不知道为什么不能。
JanT

@JanT:除了“它不会”和“它不会”之外,我没有更多的信息。我建议您提出一个更详细的新问题,以显示您尝试过的内容以及发生的确切情况。
乔恩·斯基特

我试图像您的答案中那样运行代码,但使用十进制代替了十进制。但是已经找到解决方法。干杯
JanT

1
@JanT如果您可以分享您的解决方法,那就太好了。我有完全相同的问题,可以使用该信息。谢谢!
瑞克·格里默

@RickGlimmer:我不确定您如何知道自己的问题与JanT完全相同,因为他们从来没有提供他们想要做的事情的细节。就像我期望的那样,decimaldouble我的代码替换对我来说很好用。如果您可以提供有关您要执行的操作,正在使用的代码以及结果的详细信息,那么将很容易获得帮助。
乔恩·斯基特

34

除了指定NumberStyles外,我还建议您使用decimal.TryParse函数,例如:

decimal result;
if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) )
{
     // do something in case it fails?
}

作为NumberStyles的替代方法,只要确定格式,任何人都可以使用特定的集合。例如:

NumberStyles.AllowExponent | NumberStyles.Float

1
但是不必将Float与AllowExponent一起使用,因为Float = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowDecimalPoint | AllowExponent
卢卡斯Kmoch

@LukášKmoch确实您是对的。习惯力,其他(除Any以外)不包括。不过,执行额外的OR也不应该受到伤害。
Sverrir Sigmundarson

13
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);

8

请谨慎选择答案:存在一个指定System.Globalization.NumberStyles.Float的替代性Decimal.Parse中的子类,可能会导致System.FormatException,因为您的系统可能正在等待以','而不是'。'格式的数字。

例如,以法语表示法,“ 1.2345E-02”无效,您必须首先将其转换为“ 1,2345E-02”。

总之,使用以下内容:

Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);

1
你是绝对正确的。我不明白为什么没人提起它。
卡尔斯·阿尔科里亚

10
最好使用CultureInfo.InvariantCulture作为Parse的第三个参数
Andriy Kozachuk

3

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

1

关于使用NumberStyles.Any的警告:

“ 6.33E + 03”转换为预期的6330。在德语中,小数点用逗号表示,但是6,33E + 03会转换为633000!这对我的客户来说是个问题,因为生成数据的区域性未知,并且可能不同于对数据进行操作的区域性。就我而言,我总是有科学的记号,所以我总是可以在解析之前将逗号替换为小数点,但是如果您使用的是任意数字,例如格式相当的数字(例如1,234,567),则该方法将不起作用。


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

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

希望这对某人有帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.