Android SQLite插入float类型浮点数小数位数异常(四舍五入过的两位小数变成13位小数)的原因和解决方法
浮点数异常截图:
说明:
正常保留两位小数并正确插入的记录是通过db.execSQL(sql);方法插入的,而浮点数异常的是通过ContentValues db.insert() 方式插入的,可以发现问题出在db.insert()方法上,我又试过在put的时候直接输入类似166.88存进去又是正常的。
查看db.insert源码:
public long insertWithOnConflict(String table, String nullColumnHack,
ContentValues initialValues, int conflictAlgorithm) {
acquireReference();
try {
StringBuilder sql = new StringBuilder();
sql.append("INSERT");
sql.append(CONFLICT_VALUES[conflictAlgorithm]);
sql.append(" INTO ");
sql.append(table);
sql.append('(');
Object[] bindArgs = null;
int size = (initialValues != null && !initialValues.isEmpty())
? initialValues.size() : 0;
if (size > 0) {
bindArgs = new Object[size];
int i = 0;
for (String colName : initialValues.keySet()) {
sql.append((i > 0) ? "," : "");
sql.append(colName);
bindArgs[i++] = initialValues.get(colName);
}
sql.append(')');
sql.append(" VALUES (");
for (i = 0; i < size; i++) {
sql.append((i > 0) ? ",?" : "?");
}
} else {
sql.append(nullColumnHack + ") VALUES (NULL");
}
sql.append(')');
SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
try {
return statement.executeInsert();
} finally {
statement.close();
}
} finally {
releaseReference();
}
}
可以看到是因为 put进去的float类型数据被内部做了数据类型转换. SQLiteDatabase的db.insert()
方法会根据传入的值类型自动转换数据类型,可能会导致精度丢失的问题.
ContentValues values = new ContentValues();
//values.put("id", pay.getId());
values.put("name", pay.getName());
values.put("amount", pay.getAmount());
values.put("real_amount", pay.getReal_amount());
values.put("yh_amount", pay.getYh_amount());
如何解决这个问题:?
1,将字段类型改成String
2,使用db.execSQL(sql);方法拼接原生SQL插入
3, 在java代码中做转换,使用BigDecimal来转换保存。(麻烦)
4, 将Java中定义的金额类型由float改成double(首选)
5, 将SQLite中的金额字段类型改成Integer整数,然后按最小单位处理,比如8.56保存为856做位移(大部分人的做法)
我选择了第2种或第4种(视情况),用回最原始的拼接SQL直接执行的方式,安全靠谱简单。哈哈
db.insert()
方法会根据传入的值类型自动转换数据类型,可能会导致精度丢失的问题。在SQLite中,float
类型的数据只能存储约7位有效数字,如果插入的数据精度超过了这个范围,那么SQLite会自动将其截断或四舍五入,从而导致小数位数变长的现象。如果你需要在SQLite中存储精度较高的数据,可以考虑使用
REAL
类型或NUMERIC
类型,它们都可以存储高精度的数据。另外,为了避免精度丢失的问题,你可以将float
类型改为double
类型,这样就可以存储更多位的有效数字。
得出一个结论,java中能不用float数据类型就尽量不要用
相关文章
- Android 的分裂无解,但这并不重要
- 导入旧版本Android项目时的“Unable to resolve target ‘android
- Android Studio-解决Fetching android sdk component information加载过久问题
- Android API之android.os.AsyncTask
- android Studio 快捷键(转载)
- Android studio 提示“android qemu-system-i386.exe停止工作”
- Delphi XE之路(9)Delphi XE android mutilistview
- Android学习---如何创建数据库,SQLite(onCreate,onUpgrade方法)和SQLiteStudio的使用
- android应用开发小技巧
- Android SQLite服务--创建、增删改查
- android内存管理
- android 编程规范 check list
- Android Framework 全面分析 SystemServer
- 【报错】Error inserting GREEM=30 YELLOW=4 RED=5 android.database.sqlite.SQLiteException: no such tab
- Android TextInputLayout 实现动画登录界面
- Android SQLite用sql语句进行增删改查
- 【Android笔记82】Android之Room操作SQLite数据库及其使用方法
- android.database.sqlite.SQLiteException: no such table: xxx (code 1 SQLITE_ERROR): , while compiling
- 【Android Gradle 插件】Android Plugin DSL Reference 离线文档下载 ( GitHub 下载文档 | 查看文档 )
- 【Android Gradle 插件】build.gradle 中的 android 配置 ( 配置项 | compileSdkVersion 配置 | buildToolsVersion 配置 )
- Android ActionBar添加返回按钮
- 实验六 Android Studio SQLite数据存储和访问【班级名单列表视图02】