2014-04-25 15 views
17

Wartość ciągu wynosi "90-". Dlaczego liczba dziesiętna analizuje ją jako "-90", ale double wyrzuca FormatException?Problem z analizą liczby dziesiętnej

var inputValue= "90-"; 
Console.WriteLine(decimal.Parse(inputValue)); 
Console.WriteLine(double.Parse(inputValue)); 
+2

Czy chcesz mieć '.TryParse' w swoim przykładzie kodu? – krillgar

+4

ładne pytanie dla 'Eric Lippert' –

+0

Po prostu przekazują różne wartości domyślne do parsera liczb. "Dziesiętny" jest skonfigurowany tak, aby szukać wspólnych formatów pieniężnych, a "podwójny" nie jest. – Gabe

Odpowiedz

15

Przeciążenie decimal.Parse(string s), domyślnie jest wywoływana z NumberStyleNumberStyles.Number który jest zdefiniowany jako:

Wskazuje, że AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint i AllowThousands style są używane. To jest złożony styl liczbowy.

Należy pamiętać, że AllowTrailingSign jest wliczony w cenę. Jeśli chcesz dostosować zachowanie, należy jawnie wywołać przeciążenie, które pozwala określić styl numeru i dostosować go do swoich potrzeb.

4

Interesujące wydaje się, że domyślnie decimal i double stosować różne style numer:

http://msdn.microsoft.com/en-us/library/cafs243z.aspx

Parametr s jest interpretowany przy użyciu stylu NumberStyles.Number. Oznacza to, że dozwolona jest biała spacja i separatory tysięcy, ale symbole walutowe nie są dozwolone.

http://msdn.microsoft.com/en-us/library/fd84bdyt(v=vs.110).aspx

S parametr jest interpretowany przy użyciu kombinacji flag NumberStyles.Float i NumberStyles.AllowThousands. Oznacza to, że na przykład dozwolona jest biała spacja i separatory tysięcy, podczas gdy symbole walut nie są.

To nie jest oczywiste z tych opisów, ale jeśli spojrzeć go, NumberStyles.Number pozwala spływu znak:

http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx

wskazuje, że AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, i style AllowThousands są używane. To jest złożony styl liczbowy.

Prawdopodobnie różnica w wartościach domyślnych wynika z faktu, że decimal jest często używany do obliczania waluty.

Oczywiście w obu przypadkach można podać własny format liczbowy, określając dokładnie to, co robisz i czego nie chcesz zaakceptować, abyś mógł je dostosować do własnego użytku.

8

Realizacja różni się między nimi:

public static double Parse(String s) { 
    return Parse(s, NumberStyles.Float| NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo); 
} 

public static Decimal Parse(String s) { 
    return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo); 
} 

gdzie

NumberStyles.Float  = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | 
         AllowDecimalPoint | AllowExponent, 

NumberStyles.Number = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign | 
         AllowDecimalPoint | AllowThousands 

Więc decimal.Parse pozwala spływu oznaki ale double.Parse nie.

Wygląda jak documentation na MSDN jest niedokładna:

Parametr s zawiera szereg postaci:

[WS] [znak] [cyfry] cyfry [.fractional-cyfry] [ WS]

należy wskazać, że spływu znak jest ważny, jak również.

Powiązane problemy