Laden...

Daten in DB falsch!

Erstellt von mattulla vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.091 Views
M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren
Daten in DB falsch!

Hallo,

ich habe ganz normal ueber ODBC eine PostgreSQL-DB angesteuert. Ich habe eine Tabelle dann um 2 Spalten erweitert und einen Algorithmus entworfen welcher mir die beiden Spalten mit sinnigen Testdaten fuellt. Beim genauen betrachten der Daten wurde dann aber klar, dass diese falsch waren. Nach ewigen suchen im Algorithmus und so habe ich dann den Fehler gefunden:

Die Daten wurden alle korrekt berechnet und es wurde ein richtiges SQL-Statement erstellt nur in der Datenbank sind andere Daten angekommen. Ein Beispiel:

SQL-Statement:
"UPDATE feature SET lat = 9.0900064, lon = 7.3054523 WHERE id = 12;"

Die Werte in der Tabelle sind danach die folgenden:
lat = 9.0900068
lon = 7.3054523

In diesem Fall ist der Wert bei lon sogar ausnahmsweise mal komplett richtig nur der lat-Wert haut in der letzten Stelle gleich um 4 raus. Die Abweichungen sind bei anderen Datensaetzen sogar teils noch groesser.
Kann mir hier vll jemand erklaeren wie so etwas zu stande kommt und vor allem wie ich das Problem beheben kann?

Danke
mattulla

P
123 Beiträge seit 2006
vor 17 Jahren

ich denke das evtl. an den falschen Datentypen liegt!

Welche verwendest du im Code bzw. Datenbank?

Wenn möglich versuche mit Parameter zu arbeiten und gebe dort dann den Datentyp mit.

Hier mal der Constructor der OdbcParameter Klasse!
Wichtig ist dabei der OdbcType!


C# 
public OdbcParameter (
	string name,
	OdbcType type
)
 

Parameter
name
Der Name des Parameters. 

type
Einer der OdbcType-Werte. 

Gruss plongo


Woher soll ich wissen, was ich denke, bevor ich höre, was ich sage!
Kurzum: Läufer sind gesünder, "gescheiter" und glücklicher als Nichtläufer.
www.andreas-nicole.de

S
8.746 Beiträge seit 2005
vor 17 Jahren

Riecht nach Konvertierung von float nach double, bzw. umgekehrt.

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Alsoim Code rechne ich mit double, die Spalte in der DB ist mit float(8) angelegt. Sollte aber doch eingentlich egal sein.....es wird doch der von mir oben gepostetet String gesendet und nicht der double-Wert.

Die Sache mit den Parametern ist vll wirklich nicht ganz gute Idee. Nen Kollege hatte mir alternativ schon ADO.NET vorgeschlagen. Was ist denn davon zu halten?

347 Beiträge seit 2006
vor 17 Jahren

Original von mattulla
es wird doch der von mir oben gepostetet String gesendet und nicht der double-Wert. In der DB ist es aber ein Float. Das heißt du hast einer Ungenauigkeit zugunsten von Performance zugestimmt.
Durch double statt Decimal hast du das gleiche auch auf der .Net-Seite gemacht. 😉
Ein virtueller scalarer Typ, der exakt den Wert halten wird, den du angibst wäre (je nach DBMS):*Number(X, Y) *Decimal *Numeric *Currency

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Mhhh naja verstehe die Sache zwar immer nohc nicht so ganz weil ja die noetige Anzahl an Nachkommastellen vorhanden ist da nur am Ende die falschen Werte reinkommen aber egal...

Also muss ich in der DB jetzt anstatt von float eine Art double nehmen. Die Sache hab ich schon mal versucht bin aber gescheitert und habe deshalb dann float genommen (schien mir auch erst genau genug zu sein). Bei der Datenbank handelt es sich um eine PostgreSQL.....mom fuege ich die Spalte so hinzu:

ALTER TABLE feature ADD COLUMN angle float(8);

Waere echt super nett wenn mir noch kurz einer auf die Spruenge helfen koennte wie genau ich das SQL-Statement abaendern muss.

Danke noch mal fuer die Geduld und auch alles andere!

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Alles klar die richtige Antwort hatte robert ja eben schon gegeben mit decimal gehts......

.....verstanden hab ich das mit den Abweichungen bei float aber trotzdem nicht.....nen Rundungsfehler in der letzten Stelle waere ja nachvollziehbar aber auf die Sache kann ich mir einfach keinen Reim machen.

6.862 Beiträge seit 2003
vor 17 Jahren

Schau dir mal an wie Fließkommadatentypen implementiert sind, man kann nicht jede Zahl genau speichern. Deshalb haben die Datentypen ne bestimmte Präzision bis wohin die genau arbeiten, und manchmal können Zahlen gar net genau gespeichert werden.
Deshalb sollte man Fließkommadaten auch nie als z.b. exakte Abbruchbedingung für Schleifen nutzen.

Baka wa shinanakya naoranai.

Mein XING Profil.

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Ich weiss....das gute alte Binaersystem. Aber wenn ich schon einen float-Wert mit 7 Nachkommastellen ablegen kann werde ich doch auch wohl erwarten duerfen, dass auch die 7. Stelle nach dem Komma max. einen Rundungsfehler aufweist. Wenn dem nicht der Fall ist, ist es aus meiner Sicht voellig unsinnig dem Anwender die 7. Nachkommastelle ueberhaupt noch anzuzeigen und ihn so in der Annahme zu lassen Daten zu haben die auf 7 Nachkommastellen genau sind. Aus meiner Sicht duerften einfach nur 6 Nachkommastellen moeglich sein, dann bekommt auch jeder sofort mit, dass der gewaehlte Datentyp unzureichend ist und benutzt nen anderen.

6.862 Beiträge seit 2003
vor 17 Jahren

Die Nachkommastellen haben doch nichts damit zu tun dass die Zahl nicht genau gespeichert werden können. Du kannst mit float die Zahl 3.402823^38 darstellen und die passt aufs Bit, 0.25 dagegen ist binär mit Fließkommazahlen nicht genau speicherbar. Die Anzahl der Stellen einer Zahl hat nur bedingt damit was zu tun.

Außerdem tun doubles net weh bei heutigen Computern. Deshalb sind Gleitkommazahlen in .Net implizit immer doubles.

Baka wa shinanakya naoranai.

Mein XING Profil.

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Aber je nach dem wieviele Bits genutzt werden kommt man immer dichter an die Zahl ran. Am Beispiel der 0.25 erhaelt man (jetzt nur beispielhaft ausgedacht) mit 16 Bit die Zahl: 0,250.000.424....

Was ich nun meine, ist dass es nicht i.O. ist, in einem Fall wie diesen 9 Nachkommastellen anzugeben. Es ist doch vorher bekannt, dass bei 16 Bit wie in meinem Beispiel die ersten Fehler an der 7. Nachkommastelle auftreten. Also sollten aus meiner Sicht auch nur 6 Nachkommastellen angezeigt werden. So bekommt man max. einen Rundungsfehler.
Wenn dann mehr Bits wie bei double zur verfuegung stehen kann die Zahl ja auch weiter angezeigt werden. Es geht halt nur darum, dass man keine Nachkommastellen zur Verfuegung stellt bei denen man nicht weiss, dass sie noch richtig sind.

Aehnliche Sachen kann man uerall im Leben beobachten, im Sport werden beim 100m-Lauf beispielsweise auch nur 3 Nachkommastellen gewertet. Einfach aus dem Grund weil man die nachfolgenden Stellen nicht bestimmen kann und wenn man sie trotzdem mit angibt mit ziemlicher Sicherheit was falsches angibt.

6.862 Beiträge seit 2003
vor 17 Jahren

Wieso? Dein lon Wert ist doch richtig, dein lat Wert nur falsch. Wie gesagt, kommt immer drauf wie gut sich die Zahl darstellen lässt. Außerdem hast du sie doch als Zahl mit soviel Stellen direkt im String angegeben =) Wieso soll dir irgendwer jetzt auf einmal Stellen verschweigen?

Baka wa shinanakya naoranai.

Mein XING Profil.

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

verschweigen soll mir die Stellen keiner nur bitte richtig anzeigen wenn sie schon angezeigt werden. Das der eine Wert passt war halt gerade in dem Fall nen Gluecksgriff. Man muss immer davon ausgehen welche Nachkommastelle im schlechtesten Fall nen Fehler hat und nicht wie weit man in nem guenstigen Fall richtig liegt, sonst koennte man stets 100 oder noch mehr Stellen angeben

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Naja auf jeden Fall hab ich gerade mein naechstes Problem. Da ein anderes Programm welches ich nicht geschrieben hab, aus mir nicht ersichtlichen Gruenden nicht damit klar kommt wenn ich die Spalte mit

"ALTER TABLE feature ADD COLUMN lat decimal;"

anlege wollte ich die Nachkommastellen direkt auf 7 festlegen. Soweit ich das nachgeschlagen habe sollte das auch gehn....wie gesagt sollte

"ALTER TABLE feature ADD COLUMN lat decimal(3,7);"

Beim Ausfuehren der Sache erhalte ich dann den Hinweis, dass der persission zwischen 0 und 3 sein muss.

Hat vll wer ne Idee wie ich es trotzdem auf 7 Nachkommastellen schaffe?

6.862 Beiträge seit 2003
vor 17 Jahren

Original von mattulla
Man muss immer davon ausgehen welche Nachkommastelle im schlechtesten Fall nen Fehler hat und nicht wie weit man in nem guenstigen Fall richtig liegt

Ja, bei 0.33 stimmt aber schon die zweite Stelle net, selbst bei double 🙂

Baka wa shinanakya naoranai.

Mein XING Profil.

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

vll etwas ungluecklich ausgedrueckt, dass die Stelle stimmen muss. Wichtig ist wie gross der Fehler ist. Bei 0.33 kommt bei double mit Sicherheit so etwas wie 0.329999999999999999994465456654 raus. So ein Ergebnis ist doch wohl unumstritten besser als 0.333333454656468.

Wenn man beispielsweise 0.25 angibt sollte der Fehlter < 0.005 sein, gibt man 0.253 an sollte der Fehler < 0.0005 sein. Genauso verhaelt es sich auch mit der 0.33

6.862 Beiträge seit 2003
vor 17 Jahren

Deshalb haben Floating Point Datentypen nen Property das nennt sich Epsilon 😉 Des benutzt man um den Ungenauigkeiten ausm weg zu gehen.

Baka wa shinanakya naoranai.

Mein XING Profil.

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Dummerweise nuetzt mir sowas nix bis gar nix

M
mattulla Themenstarter:in
99 Beiträge seit 2006
vor 17 Jahren

Das Problem mit den varialbeln Nachkommastellen bin ich los....mit decimal(10,7) klappt es