Benutzer mit den meisten Antworten
Werte werden "ungenau" aus Textdatei eingelesen

Frage
-
Hi,
ich möchte Werte aus einer Textdatei einlesen, die ich dann in ein Array mit doppelter Genauigkeit schreibe. Das Problem ist nun, dass die Werte nicht exakt übernommen werden. Die Erste Zahl in der Textdatei lautet z.B. -3,81. In das Array wird aber -3.809999942779541 geschrieben. Die Abweichung ist zwar gering, aber ich brauche die hohe Genauigkeit. Ich vergleiche zwei Temperaturfelder auf Unterschiede, und wenn schon die Ausgangswerte nicht exakt eingelesen werden, klappt das natürlich nicht.
Hier der Programmcode für das Einlesen. Hat jemand eine Idee, wie die ungenauigkeiten entstehen?
REM ProgressivBar1 auf Schichttemperaturen lesen vorbereiten ProgressBar1.Value = 0 ProgressBar1.Maximum = YMAX REM Schichttemperaturen lesen LabelProgressivBar.Text = "Schichttemperaturen einlesen" Refresh() Dim sr As New StreamReader("C:\FEM-DA\10mm-DA.txt") For y As Integer = 0 To YMAX Temp2D(y) = Convert.ToSingle(sr.ReadLine()) ProgressBar1.PerformStep() Next
Gruß, Thomas
Antworten
-
Temp2D(y) = Convert.ToDouble(sr.ReadLine())
... konvertiere den string in eine Zahl vom Typ double.
(Eventuell auch interressant double.Parse und double.TryParse faalls Du nicht vorher genau weißt, dass der Text in einen Double gewandelt werden kann http://msdn.microsoft.com/de-de/library/system.double.tryparse(v=vs.100).aspx )
Du wolltest doch doppelte Genauigkeit? (Die Abweichung kommt, davon, dass ein Single die Zahl eventuell nicht exact abbilden kann. http://de.wikipedia.org/wiki/Gleitkommazahl )
Viele Grüße,
Thorsten
- Bearbeitet Thorsten Gudera Donnerstag, 19. April 2012 12:30
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller) Donnerstag, 19. April 2012 15:43
- Als Antwort markiert ThomasPeterSN Donnerstag, 19. April 2012 17:37
-
Wichtig ist zu verstehen, dass die interne binäre Darstellung gebrochener Zahlen und die Umwandlung dieser binären Darstellung in eine dezimale Darstellung mit Rundungsdifferenzen behaftet sein kann. Die dezimale Darstellung der Zahl 3,81 lässt sich nicht genau in eine kurze binäre Mantisse (Single) umwandeln. Da werden einige benötigte Bits abgeschnitten. Wenn solch eine Gleitkommazahl dann zurück in eine dezimale Darstellung umgewandelt wird und die maximal mögliche Zahl dezimaler Nachkommastellen genutzt wird, kann es zu dem beobachteten Ergebnis kommen.Es gibt 3 Lösungswege:- Rundung der Darstellung- Nutzung einer langen Gleitkommadarstellung (Double)- Nutzung des Typs Decimal--
Viele Gruesse
Peter- Als Antwort markiert ThomasPeterSN Freitag, 20. April 2012 06:21
Alle Antworten
-
Temp2D(y) = Convert.ToDouble(sr.ReadLine())
... konvertiere den string in eine Zahl vom Typ double.
(Eventuell auch interressant double.Parse und double.TryParse faalls Du nicht vorher genau weißt, dass der Text in einen Double gewandelt werden kann http://msdn.microsoft.com/de-de/library/system.double.tryparse(v=vs.100).aspx )
Du wolltest doch doppelte Genauigkeit? (Die Abweichung kommt, davon, dass ein Single die Zahl eventuell nicht exact abbilden kann. http://de.wikipedia.org/wiki/Gleitkommazahl )
Viele Grüße,
Thorsten
- Bearbeitet Thorsten Gudera Donnerstag, 19. April 2012 12:30
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller) Donnerstag, 19. April 2012 15:43
- Als Antwort markiert ThomasPeterSN Donnerstag, 19. April 2012 17:37
-
Richtig, ich wollte ein Array mit doppelter Genauigkeit, das war mein Fehler im Programmcode. Die Zahl, die ich einlesen wollte, hat aber doch nur zwei Kommastellen, da dachte ich, dass auch ein Array mit einfacher Genauigkeit die exakt abbilden kann. Bei einer Zahl wie z.B. -3,81 in der Textdatei hätte ich -3.810000000000000 im Array erwartet.
Wie auch immer, ich habe den Programmcode geändert und es funktioniert. Ich werde mal den Wikipedia-Artikel studieren, vielleicht weiß ich hinterher auch, warum. ;-)
Vielen Dank für die Hilfe.
Gruß, Thomas
-
Richtig, ich wollte ein Array mit doppelter Genauigkeit, das war mein Fehler im Programmcode. Die Zahl, die ich einlesen wollte, hat aber doch nur zwei Kommastellen, da dachte ich, dass auch ein Array mit einfacher Genauigkeit die exakt abbilden kann. Bei einer Zahl wie z.B. -3,81 in der Textdatei hätte ich -3.810000000000000 im Array erwartet.
Wie auch immer, ich habe den Programmcode geändert und es funktioniert. Ich werde mal den Wikipedia-Artikel studieren, vielleicht weiß ich hinterher auch, warum. ;-)
Vielen Dank für die Hilfe.
Gruß, Thomas
Hallo Thomas,
bitte lese: Standard numeric format strings Die Ausgabe Formatierung einer Zahl Kannst Du damit steuern.
3.81000000000 muss nicht sein.
Gruss Ellen
Ich benutze/ I'm using VB2008 & VB2010
-
Hallo Ellen,
das Formatieren der Zahl ist nicht mein Problem. Ich hätte nichts dagegen, wenn nach dem Einlesen der -3,81 aus der Textdatei im Array -3.810000000000000 stehen würde. Dort stand aber -3.809999942779541, zumindest solange ich den Wert aus der Textdatei mit ConvertToSingle() eingelesen habe. Mit ConvertToDouble() klappte es dann.
Hallo Koopakiller,
ich weiß nicht, ob ich Deine Vermutung richtig verstehe. In der Textdatei, aus der ich einlese sind 2000 Zeilen enthalten. In jeder Zeile steht eine Zahl mit max. zwei Kommastellen. Alle 2000 Zahlen werden korrekt in das Array eingelesen, allerdings jede Zahl mit einer (geringen) Ungenauigkeit. Ich weiß nicht, ob das so passieren würde, wenn jeweils vier Byte zuviel ausgelesen werden würden.
Gruß, Thomas
- Bearbeitet ThomasPeterSN Donnerstag, 19. April 2012 20:09
-
Wichtig ist zu verstehen, dass die interne binäre Darstellung gebrochener Zahlen und die Umwandlung dieser binären Darstellung in eine dezimale Darstellung mit Rundungsdifferenzen behaftet sein kann. Die dezimale Darstellung der Zahl 3,81 lässt sich nicht genau in eine kurze binäre Mantisse (Single) umwandeln. Da werden einige benötigte Bits abgeschnitten. Wenn solch eine Gleitkommazahl dann zurück in eine dezimale Darstellung umgewandelt wird und die maximal mögliche Zahl dezimaler Nachkommastellen genutzt wird, kann es zu dem beobachteten Ergebnis kommen.Es gibt 3 Lösungswege:- Rundung der Darstellung- Nutzung einer langen Gleitkommadarstellung (Double)- Nutzung des Typs Decimal--
Viele Gruesse
Peter- Als Antwort markiert ThomasPeterSN Freitag, 20. April 2012 06:21
-
Ich glaube, jetzt habe ich es begriffen. Mit der doppelten Genauigkeit klappt das Einlesen jetzt auch so, wie es soll. Mit dem Typ Decimal werde ich mich auch mal beschäftigen, den habe ich bisher nie benutzt.
Danke an alle für die Hilfe.
Gruß, Thomas