none
Typkonvertierung in Double RRS feed

  • Frage

  • Hallo zusammen,

    ich habe eine Software, die mit verschiedenen Ländereinstellungen klar kommen soll. Es gibt irgendwo im Programm Typkonvertierungen zu Double. Man kann davon ausgehen, dass nirgends Tausender-Trennzeichen verwendet werden. Man hat also immer nur das Dezimaltrennzeichen.

    Reicht es hier, wenn man einfach mit

    double val = Convert.ToDouble(..., CultureInfo.InvariantCulture)

    den gegebenen Wert in ein double konvertiert? Wird das dann immer richtig gemacht, egal, ob das Programm nun mit "." oder "," als Dezimaltrennzeichen arbeitet?

    Was wäre für das gegebene Szenario, die beste Variante zum Konvertieren??

    Montag, 27. September 2010 08:25

Antworten

  • double v = 12345.12345;
    var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
    var all = cultures.Where( cult => !cult.IsNeutralCulture).Select(cult =>
    {
      return new {Name = cult.Name, S = v.ToString(cult) };
    });
    
    char[] digits = "1234567890".ToCharArray();
    
    foreach (var s in all)
    {
      Console.Write(s.Name);
      Console.Write(": ");
      Console.Write(s.S);
      Console.Write(" => ");
      try
      {
        var nfi = new NumberFormatInfo();
        nfi.NumberDecimalSeparator = s.S.Trim(digits);
        double d = Convert.ToDouble(s.S, nfi);
        Console.Write(d.ToString());
        Console.Write(" => ");
        double d2 = Convert.ToDouble(s.S, CultureInfo.InvariantCulture);
        Console.Write(d2.ToString());
      }
      catch
      {
        Console.Write("Error");
      }
      finally
      {
        Console.WriteLine();
      }
    }
    
    Hmm.. sieht gut aus.
    Montag, 27. September 2010 13:06
  • Hallo SP.,

         > Das Problem ist, dass ich hier keine verschiedenen Kultur-Einstellungen simulieren
         > kann, da mein Rechner auf DE eingestellt ist.

    doch, das geht zum Beispiel mit:

      Thread t = Thread.CurrentThread;
      CultureInfo zuSimulierendeKultur = new CultureInfo("en-US");
      t.CurrentCulture = zuSimulierendeKultur;
      t.CurrentUICulture = zuSimulierendeKultur;


    ciao Frank

    Montag, 27. September 2010 14:16
  • Hallo S.,

    Bei einer evtl. Speicherung von double-Werten als Text verwende CultureInfo.InvariantCulture, um die Speicherung der Daten in einer Kultur-insensitiven Art zu gewährleisten. So hast Du beim erneuten Einlesen weniger Kopfzerbrechen. Für alle anderen Fälle: Stelle ein und verwende die gewünschte Thread.CurrentThread.CurrentCulture. Bei der Konvertierung mußt Du dann keine CultureInfo angeben.

    Gruß
    Marcel

    Montag, 27. September 2010 17:10
    Moderator

Alle Antworten

  • Mit "," und "." scheint das ja schon zu versagen, oder nicht?

    string[] ds = new string[] {
      "12354456,1234","12354456.1234","12354456%1234","12354456->1234","1235445۩61234","1235445͏61234"};
    char[] digits = "1234567890".ToCharArray();
    
    foreach (var s in ds)
    {
      Console.Write(s);
      Console.Write(" => ");
      try
      {
        var nfi = new NumberFormatInfo();
        nfi.NumberDecimalSeparator = s.Trim(digits);
        double d = Convert.ToDouble(s, nfi);
        Console.Write(d.ToString());
        Console.Write(" => ");
        double d2 = Convert.ToDouble(s, CultureInfo.InvariantCulture);
        Console.Write(d2.ToString());
      }
      catch {
        Console.Write("Error");
      }
      finally
      {
        Console.WriteLine();
      }
    }
    
    

    Das hier dürfte wenigstens alles erschlagen, was mit "Arabischen" Zahlen arbeitet.

     

    Montag, 27. September 2010 10:58
  • Das Problem ist, dass ich hier keine verschiedenen Kultur-Einstellungen simulieren kann, da mein Rechner auf DE eingestellt ist.
    Montag, 27. September 2010 12:46
  • double v = 12345.12345;
    var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
    var all = cultures.Where( cult => !cult.IsNeutralCulture).Select(cult =>
    {
      return new {Name = cult.Name, S = v.ToString(cult) };
    });
    
    char[] digits = "1234567890".ToCharArray();
    
    foreach (var s in all)
    {
      Console.Write(s.Name);
      Console.Write(": ");
      Console.Write(s.S);
      Console.Write(" => ");
      try
      {
        var nfi = new NumberFormatInfo();
        nfi.NumberDecimalSeparator = s.S.Trim(digits);
        double d = Convert.ToDouble(s.S, nfi);
        Console.Write(d.ToString());
        Console.Write(" => ");
        double d2 = Convert.ToDouble(s.S, CultureInfo.InvariantCulture);
        Console.Write(d2.ToString());
      }
      catch
      {
        Console.Write("Error");
      }
      finally
      {
        Console.WriteLine();
      }
    }
    
    Hmm.. sieht gut aus.
    Montag, 27. September 2010 13:06
  • Hallo SP.,

         > Das Problem ist, dass ich hier keine verschiedenen Kultur-Einstellungen simulieren
         > kann, da mein Rechner auf DE eingestellt ist.

    doch, das geht zum Beispiel mit:

      Thread t = Thread.CurrentThread;
      CultureInfo zuSimulierendeKultur = new CultureInfo("en-US");
      t.CurrentCulture = zuSimulierendeKultur;
      t.CurrentUICulture = zuSimulierendeKultur;


    ciao Frank

    Montag, 27. September 2010 14:16
  • Stellt sich hier dann wirklich die Culture so ein, dass überall im Programm die Converts auf dieses eingestellte Culture zugreifen?
    Montag, 27. September 2010 14:25
  • Hallo SP.,

         > Stellt sich hier dann wirklich die Culture so ein, dass überall
         > im Programm die Converts auf dieses eingestellte Culture zugreifen?


    ja, wenn Du nur in diesem Thread arbeitest (wäre Standard in Windows Forms). Wenn Du neue Threads erzeugst, müsstest Du deren Locale anpassen, da die das Standard-Locale annehmen.

    Aber man kann auch die gesamte Kultur ändern, indem man das zum Beispiel über die regionlen (Windows) Einstellungen angibt.

         [Windows-R] rundll32.exe shell32,Control_RunDLL intl.cpl

    [.NET User Interface Culture]
    http://www.sisulizer.com/online-help/ActionMessageNetUiLocale.shtml 


    ciao Frank
    Montag, 27. September 2010 14:38
  • Hallo S.,

    Bei einer evtl. Speicherung von double-Werten als Text verwende CultureInfo.InvariantCulture, um die Speicherung der Daten in einer Kultur-insensitiven Art zu gewährleisten. So hast Du beim erneuten Einlesen weniger Kopfzerbrechen. Für alle anderen Fälle: Stelle ein und verwende die gewünschte Thread.CurrentThread.CurrentCulture. Bei der Konvertierung mußt Du dann keine CultureInfo angeben.

    Gruß
    Marcel

    Montag, 27. September 2010 17:10
    Moderator