指数表記から数値を解析する


85

文字列「1.2345E-02」(指数表記で表された数値)を10進データ型に解析する必要Decimal.Parse("1.2345E-02")がありますが、単にエラーがスローされます

回答:


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

これがデフォルトでサポートされていない理由は完全にNumberStyles.Numberはわかりません。デフォルトでは、AllowLeadingWhite、AllowTrailingWhite、AllowLeadingSign、AllowTrailingSign、AllowDecimalPoint、およびAllowThousandsスタイルを使用するを使用します。おそらくそれはパフォーマンスに関連しています。指数を指定することは比較的まれだと思います。


私はこれをdoubleで動作させようとしていますが、そうではないようです。なぜできなかったのかわからない..?
JanT

@JanT:「それはしない」と「それはできなかった」以外の情報がなければ、私は本当にこれ以上助けることはできません。何を試し、何が起こったのかを正確に示して、より詳細に新しい質問をすることをお勧めします。
ジョンスキート

私はあなたの答えのようにコードを実行しようとしましたが、10進数の代わりにdoubleを使用しました。しかし、すでに回避策が見つかりました。乾杯
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.Anyの代わりに、特定の形式がわかっている場合は、特定のセットを使用できます。例えば:

NumberStyles.AllowExponent | NumberStyles.Float

1
ただし、Float = AllowLeadingWhite |であるため、AllowExponentでFloatを使用する必要はありません。AllowTrailingWhite | AllowLeadingSign | AllowDecimalPoint | AllowExponent
ルカシュKmoch

@LukášKmoch確かにあなたは正しいです。他の人(Anyを除く)のような習慣の力にはそれが含まれていません。ただし、追加のORを実行しても問題はありません。
Sverrir Sigmundarson 2017年


8

選択した回答には注意してください。Decimal.ParseSystem.Globalization.NumberStyles.Floatを指定する微妙な点があり、システムが「。」ではなく「、」でフォーマットされた数値を待機している可能性があるため、System.FormatExceptionが発生する可能性があります。

たとえば、フランス語表記では、「1.2345E-02」は無効です。最初に「1,2345E-02」に変換する必要があります。

結論として、次の線に沿って何かを使用します。

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

1
あなたは絶対に正しいです。なぜ誰もそれを持ち出さなかったのか分かりません。
Carles Alcolea 2017年

10
解析の3番目のパラメーターとしてCultureInfo.InvariantCultureを使用することをお
勧めし

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

入力を使用することをお勧めします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);
}

これが誰かを助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.