2016-01-27 7 views
7

Występuje dziwne zachowanie podczas przekształcania liczby w liczbę podwójną podczas korzystania z informacji o kulturze.
Konwersja "3,3" przy użyciu kultury holenderskiej jest obsługiwana poprawnie. Jeśli skonwertuję "3,3" przy użyciu kultury amerykańskiej, zwróci ona 33. Spodziewałem się błędu. Zobacz mój przykład:Liczba z separatorem dziesiętnym niepoprawnie rzutowana na podwójnie

static void Main(string[] args) 
{ 
    CultureInfo cultureDutch = new CultureInfo("nl-NL"); 
    CultureInfo cultureUS = new CultureInfo("en-US"); 

    System.Threading.Thread.CurrentThread.CurrentCulture = cultureDutch; 
    Console.WriteLine("Input 3,3 --> Expected 3,3"); 
    Console.WriteLine("Output = " + Convert.ToDouble("3,3", cultureDutch)); 
    // Actual result --> 3,3 

    Console.WriteLine("Input 3,3 --> Expected InvalidCastException"); 
    Console.WriteLine("Output = " + Convert.ToDouble("3,3", cultureUS)); 
    // Actual result --> 33 

    Console.WriteLine(); 
    Console.WriteLine(); 

    System.Threading.Thread.CurrentThread.CurrentCulture = cultureUS; 
    Console.WriteLine("Input 3.3 --> Expected InvalidCastException"); 
    Console.WriteLine("Output = " + Convert.ToDouble("3.3", cultureDutch)); 
    // Actual result --> 33 

    Console.WriteLine("Input 3.3 --> Expected 3.3"); 
    Console.WriteLine("Output = " + Convert.ToDouble("3.3", cultureUS)); 
    // Actual result --> 3.3 
    Console.ReadLine(); 
} 

Jaki jest prawidłowy sposób obsługi tego? Wolałbym wyjątek, gdy separator dziesiętny (lub tysiąc) jest nieprawidłowy.

+0

Przecinek jest separatorem tysięcy, .NET nie jest wrażliwy na to, gdzie użytkownik je umieszcza. Albo, że użytkownik ma nieregularny wzór, tak jak Indianie. Musisz dążyć do prawdziwej poprawki i wiedzieć, jakiego języka mówi użytkownik. To nigdy nie jest prawdziwy problem, to wątek.CurrentCulture. Problem występuje tylko wtedy, gdy mówisz po holendersku i udajesz, że nie jesteś z Holandii, nie informując o tym swojego systemu operacyjnego. –

Odpowiedz

0

Wraz z odpowiedzią od Boas Enkler udało mi się rozwiązać problem. Najpierw zeskanuję dane wejściowe dla tysięcy separatorów, w oparciu o aktualną kulturę. I w końcu przeanalizuję wartość wejściową na podwójną.

private static string RemoveThousandSeparator(string input) 
    { 
     Regex removeThousandSeparatorExpr = new Regex(@"^-?(?:\d+|\d{1,3}(?:\" 
         + <CultureInfo>.NumberGroupSeparator + @"\d{3})+)(?:\" 
         + <CultureInfo>.NumberDecimalSeparator + @"\d+)?$"); 
     Match match = removeThousandSeparatorExpr.Match(input); 
     if (match.Success) 
     { 
      input = input.Replace(<CultureInfo>.NumberGroupSeparator, ""); 
     } 
     else 
     { 
      throw new Exception("Invalid input value"); 
     } 

     return input; 
    } 
2

Jeśli chcesz tylko do analizowania go użyłbym dedykowanych metod analizowania, w którym można ustawić Numberstyles

Poniższy kod będzie rzucać FormatException

var culture =new CultureInfo("en-US"); 
var result = double.Parse("3,3", NumberStyles.AllowDecimalPoint, culture); 

W celu uzyskania dalszych informacji, patrz Double.Parse Method

+0

Myślałem, że to jest odpowiedź, ale niestety tak nie jest. Ponieważ dane wejściowe mogą zawierać zarówno separatory dziesiętne, jak i tysięczne, odrzucanie tysięcy separatorów nie jest odpowiedzią. W kulturze amerykańskiej 1,000.0 jest poprawne, ale użycie AllowDecimalPoint jest uważane za nieważne. Myślę, że potrzebuję wyrażeń regularnych, aby usunąć tysiące separatorów, przed użyciem wartości w obliczeniach. –

Powiązane problemy