none
Dim d As Double = 170218.100907 NICHT möglich RRS feed

  • Frage

  • Hallo

    Habe etwas unbegreifliches entdeckt. Bei mir funktioniert die Definition 'Dim d As Double = 170218.100907' nicht! VS 2015 macht daraus immer 'Dim d As Double = 170218.10090699999'

    Kann mir jemand sagen, woran das liegt? Filterfunktionen etc. sind mit '170218.100907' nicht möglich.

    Bin gespannt auf eure Feedbacks. Danke.

    Alex

    Freitag, 3. März 2017 12:31

Antworten

Alle Antworten

  • Hallo Alex,

    nimm Decimal, nicht Double. Also bspw.:

    Dim d As Decimal = 170218.100907D

    Siehe dazu u.a.:

      http://stackoverflow.com/questions/618535/difference-between-decimal-float-and-double-in-net


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Freitag, 3. März 2017 12:35
    Moderator
  • Ciao Stefan

    Danke für deine Info. Das regt mich noch mehr zum Nachdenken an und passt nicht in meine Logik.

    Diese Zahl ist bei mir rein zufällig in einer Datatable entstanden und der Filter mit dieser Zahl hat einfach nicht funktioniert. Ich brauchte echt Zeit und Nerven, rauszufinden, woran es liegt.

    Die Zahlen werden aus einer Text-Datei in eine Datatable gelesen und dabei von Text in Dbl (nun Decimal) umgewandelt... Mal sehen, wie das aufgeht. grrr

    Die Frage bleibt: Wieso nur '170218.100907'?

    Gruess

    Alex

    Sonntag, 5. März 2017 09:53
  • Hi Alex,
    die Mantisse einer Gleitkommazahl hat nur eine bestimmte Menge Bit's. Nicht jede Bitkombination lässt sich in eine darstellbare Dezimalzahl umwandeln. Bei dieser Umwandlung entstehen automatisch Abweichungen. Ein klassisches Beispiel dafür ist die Dezimaldarstellung von 2/3 (zwei Drittel). Das kann man auch nicht genau machen.

    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Sonntag, 5. März 2017 13:09
  • Danke Peter

    Das ist natürlich richtig, was du sagst. 2/3 kann nie genau dargestellt werden. Ohne nun in die digitale Grundwissenschaft einzusteigen, habe ich doch erwartet, dass die Zahl '170218.100907', welche nicht aus einer Berechnung resultiert, sondern aus einem String in eine Double eindeutig umgewandelt wird und 'nur' 6 Kommastellen aufweist, nicht in diese Kategorie fallen würde.

    Werde mich wohl oder übel um dieses Problem herum schleichen müssen :)

    Danke für eure Hilfe

    Alex


    Montag, 6. März 2017 10:02
  • Hi Alex,
    eine Mantisse einer Gleitkommazahl hat nur 52 Bit (s.IEEE 754). In der Mantisse sind alle binären Ziffern enthalten, egal, wo das Komma steht. Deine Zahl '170218.100907' lässt sich aber nicht mit den 52 Bits darstellen. Deshalb wird durch den Compiler bei der Umwandlung der Zeichenkette '170218.100907' in ein Gleitkomma-Literal die Periode abgeschnitten. Bei der Rückumwandlung des Literals entsteht dann die angezeigte Ungenauigkeit, da die Information über die Periode fehlt.

    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Montag, 6. März 2017 10:50
  • Das ist eine Antwort vom Spezialisten. Vielen Dank.

    Werde mal deine HP anschauen. Gib sicherlich noch was darin zu lernen.

    Gruess

    Alex

    Montag, 6. März 2017 11:00
  • Hallo,
    folgender Code funktioniert:

    public static void Main(string[] args) {
      double x = 170218.100907;
      Thread.CurrentThread.CurrentCulture = 
        CultureInfo.GetCultureInfo("EN-US");
      x = double.Parse("170218.100907");
    }

    Der Debugger zeigt dann folgendes an:

    Ist zwar C#, sollte sich aber ohne Probleme auf Visual Basic.net übertragen lassen.


    Viele Grüße Holger M. Rößler


    Montag, 6. März 2017 14:30
  • Hi Holger,
    die Bildung von Literalen durch den Compiler funktioniert in VB.NET anders:

          Dim x As Double = 170218.10090699999
          Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("EN-US")
          Dim y = Double.Parse("170218.100907")
          Console.WriteLine(x)
          Console.WriteLine(y)
          Console.ReadKey()


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Montag, 6. März 2017 15:30