Announcement

Collapse
No announcement yet.

dbExpress ClientDataSet beschneidet Präzision von floats

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • dbExpress ClientDataSet beschneidet Präzision von floats

    Hallo,

    wenn ich folgendes probiere:
    Code:
    float test=1.2345E-12;
    SQLQuery1->SQL->Add("select * from "+DataBase+" ;");   
    ClientDataSet1->Open();
    ClientDataSet1->Edit();
    ClientDataSet1->Insert();
    ClientDataSet1->FieldByName("INDX")->Value=NULL;
    ClientDataSet1->FieldByName("avSigma")->Value=test;
    ClientDataSet1->Post();
    ClientDataSet1->ApplyUpdates(-1);
    ClientDataSet1->Close();
    Kommt bei sehr kleinen float-Werten (wie im Beispiel) nur 0 in der Datenbank an.
    Ich habe jetzt mal per Wireshark das Datenpaket abgefangen und das ClientDataSet schickt ein Standard-Insert-Statement als String. Allerdings ist die Formatierung des Values so, dass es nicht auf engineering, sondern nur 6 Nachkommastellen des floats anzeigt.

    Wie kann ich entweder die Formatierung der Values im String ändern (habe es mit EditMask probiert, jedoch ohne Erfolg), oder noch besser: Wie kann ich den float binär übertragen, anstatt den Umweg über den String?
    Das Feld in der Datenbank ist natürlich ebenfalls ein float.

    Vielen Dank!

  • #2
    Schau Dir mal hier die Datentypen an, floating point Typen gibt es verschiedene:
    https://dev.mysql.com/doc/refman/5.0...int-types.html

    Wenn Du sowieso immer "sehr kleine" Werte speicherst, kannst Du auch mit einem Faktor speichern. Es ist ja nicht notwendig 20 Nullen mitzuspeichern. Entscheidend ist die benötigte Genauigkeit.
    Die Zahlen nach String zu konvertieren ist sicher der schlechteste Ansatz.
    Gruß, defo

    Comment


    • #3
      Klar ist das der schlechteste Ansatz, mit Faktor finde ich auch sehr unelegant. Wie aber kann ich die Daten mit dem ClientDataSet binär übertragen, ohne dass ich gleich einen BLOB bemühe?

      Comment


      • #4
        Originally posted by bodo2407 View Post
        Klar ist das der schlechteste Ansatz, mit Faktor finde ich auch sehr unelegant. Wie aber kann ich die Daten mit dem ClientDataSet binär übertragen, ohne dass ich gleich einen BLOB bemühe?
        Wie kommst Du auf BLOB?!
        Also der Reihe nach, das Problem hat 2 Seiten, Client und Datenbank. Ist das Delphi, C++?
        Delphi kann auf seiner Seite verschiedene Typen verwenden, z.B. Float, aber auch BCD (glaub ich). Das muss schon mal sauber sein.
        Die Datenbank kann Floats verschiedener Genauigkeit, float, double, ... Das muss auch sauber sein.

        Unabhängig von der Speicherung ist die Anzeige, die sich meist an den Länderformateinstellungen des Systems orientiert. Die sind nicht optimal für sehr kleine Werte. Auf Feldebene gibt es z.B. Displayformat als property, um das zu regulieren.
        Gruß, defo

        Comment


        • #5
          Ich verwende dbExpress innerhalb c++ builder.
          Das Problem liegt ganz klar innerhalb der ClientDataSet-Komponente bei der Übergabe an die SQL, denn wenn ich ein Insert-Statement a la "insert into database (bla) values (1.32E-15);" benutze, kann ich den Wert ohne weiteres ebenfalls mit dem ClientDataSet richtig zurück lesen.
          Das Problem liegt in der Anweisung
          ClientDataSet1->FieldByName("avSigma")->Value=test;
          Hier wird ein String generiert, anstatt die Werte binär zu übertragen (wie es beim BLOB der Fall wäre).
          Es gibt auch diverse andere Methoden wie
          ClientDataSet1->FieldByName("avSigma")->AsFloat=test;
          jedoch haben diese alle dasselbe zum Resultat.
          Mir ist jedoch nicht klar, wie ich echte floats mittels dbExpress übergeben kann, statt deren String-Derivate. Eigentlich war ich überzeugt, dass das so gehandelt wird, bis ich das Paket abgefangen hatte...

          Comment


          • #6
            Vielleicht ist es ein Bug. Mir ging es nur darum, das Daten und CLientseitig die Dimensionierung ausreichend ist.
            Fängst Du die Stringpakete auch ab, wenn Du asFloat Notation verwendest?
            Hast Du mit Double getestet?
            Ansonsten wie gesagt ftCurrency, ftBCD probieren und mal die Werteübergabe per Query und Parameter als Update versuchen.

            Achso und als Workaround nicht per BLOB, höchstens als Varchar. Ggf direkt mit expliziter Konvertierung also bei mysql "CAST".
            Gruß, defo

            Comment

            Working...
            X