2012-04-14 4 views
4

Когда я сохраняю значение с плавающей точкой SQLiteDatabase.insert шириной, в сохраненном значение будет отличаться от оригинала, см ниже:Android разработка - SQLite хранение поплавка

У меня есть ширина базы данных:

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

Когда я вставить, например, 33,3 ширина:

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); 

у меня это:

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

Я проверил ширина Exec:

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

и что форма работает хорошо.

любая идея?

ответ

10

Никогда не думал, что эта нить поможет кому-то еще, но все это здесь goes.

В основном ваша проблема в том, что вы используете float для типа кода Java. Поплавок с очень низкой точностью. Прочитайте поток, на который я ссылаюсь, вместе со всеми комментариями и связанным чатом. Если у вас все еще есть проблемы, напишите.

Возможно, вы знаете, что двойные значения сохраняются только на определенной точности в компьютерах. Несмотря на то, что значения выглядят странно в базе данных, это наилучшее приближение ваших значений, которые вы можете получить при использовании float. С двойным вы можете увеличить точность, но вы никогда не добьетесь идеального состояния. Возможно, если вы настаиваете на том, чтобы получить точные значения, ограничивающие реальный размер в базе данных, может быть способ пойти.

EDIT Как я не мог заставить вас поверить, что это проблема точности я включаю следующую программу:

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

Выход есть:

22.200000763 

Я предлагаю вам попробовать. Как вы видите, это именно тот номер, который вы указываете.

+0

Я даже знаю, почему я использую float и почему Google использует всюду в API. Потому что это 32 бита в 32-битном процессоре и потому, что достаточно точности. – Tectona

+0

@vkaci тогда просто не беспокойтесь о точности. Однако разница в скорости действительно не учитывается, я думаю (я никогда не обнаружил существенных различий). Вы также можете обратиться к этой теме: http://stackoverflow.com/q/1074474/1108032 –

+0

Извините. Дело здесь в том, что число составляет 22,2 и хранится как 22.2000007629395. Это не проблема точности! Поплавок равен 22.2, после ContentValues.put число все равно кажется 22.2 (getAsString, getASFloat), но во время вставки что-то происходит. Я предполагаю, что это ошибка API. – Tectona

Смежные вопросы