2012-04-14 7 views
4

Wenn ich Float-Wert speichern widt SQLiteDatabase.insert der gespeicherte Wert wird anders sein als das Original, siehe unten:Android-Entwicklung - SQLite Speicherung float

ich eine Datenbank der Breite:

db.execSQL("CREATE TABLE IF NOT EXISTS info_values (" 
    + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
    + "date DATE UNIQUE NOT NULL, " 
    + "value REAL NOT NULL)"); 

Als ich Einsatz zB 33,3 Breite:

private class inputdlg_ok implements input_dlg.ReadyListener { 
    public void ready(float newvalue) { 
     Date d = new Date(); 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     ContentValues values = new ContentValues(); 
     values.put("date", sdf.format(d)); 
     values.put("value", newvalue); 

     database.insert("info_values", null, values); 

ich habe diese bekommen:

sqlite> select * from info_values; 
83|2012-04-04 09:06:22|33.2999992370605 
84|2012-04-02 09:05:57|22.2000007629395 

Ich habe Breite exec getestet:

String sql = "INSERT INTO info_values (date, value) " + 
       "VALUES ('" + sdf.format(d) + "'," + Float.toString(newvalue) + ")"; 
database.execSQL(sql); 

und das Formular funktioniert gut.

eine Idee?

Antwort

10

Ich dachte nie, dass dieser Thread anderen hilft, aber hier ist es goes.

Grundsätzlich ist Ihr Problem, dass Sie float für den Typ im Java-Code verwenden. Float ist mit sehr geringer Präzision. Lies den Thread, auf den ich verlinke, mit allen Kommentaren und dem verknüpften Chat. Wenn Sie noch Probleme haben, schreiben Sie zurück.

Sie wissen wahrscheinlich, dass die doppelten Werte nur bis zu einer bestimmten Genauigkeit in den Computern gespeichert werden. Obwohl die Werte in der Datenbank seltsam aussehen, ist dies die beste Annäherung an Ihre Werte, die Sie erhalten können, wenn Sie float verwenden. Mit Double können Sie die Präzision erhöhen, aber Sie werden nie in den perfekten Zustand kommen. Vielleicht, wenn Sie darauf bestehen, genaue Werte zu erhalten, die die reale Größe in der Datenbank begrenzen, könnte ein Weg sein.

EDIT Da ich nicht, dass Sie glauben, dass es Problem ist ein Präzisions machen könnte ich das folgende Programm enthalten:

float f = 22.2; 
printf("The number is: %.9f\n", f); 

Die Ausgabe lautet:

22.200000763 

Ich schlage vor, Sie versuchen es. Wie Sie sehen, ist dies genau die Nummer, auf die Sie hinweisen.

+0

Ich weiß sogar, warum ich float und warum Google überall in der API verwenden. Weil es 32 Bit in einer 32-Bit-CPU ist und weil die Präzision ausreicht. – Tectona

+0

@vkaci dann mach dir keine Sorgen um die Präzision. Allerdings ist der Geschwindigkeitsunterschied wirklich vernachlässigbar (ich habe nie einen signifikanten Unterschied gefunden). Sie können auch auf diesen Thread verweisen: http://stackoverflow.com/q/1074474/1108032 –

+0

Entschuldigung. Der Fall ist hier, dass die Nummer 22.2 ist und als 22.2000007629395 gespeichert wird. Dies ist kein Präzisionsproblem! Der float ist 22.2, nach dem ContentValues.put scheint die Zahl immer noch 22.2 (getAsString, getASFloat), aber während des Einfügens passiert etwas. Ich nehme an, dass dies ein API-Fehler ist. – Tectona