在 SQLite 中存储浮点值会更改 Room DB 中的小数精度
Storing a float value in SQLite changes the decimal precision in Room DB
我需要将价格存储在我的房间数据库中。根据使用我的应用程序的国家/地区,我的小数精度可以是 2 位小数或 3 位小数。
在使用android的房间库将float甚至double值存储在sqlite数据库中时,它改变了值。例如:
14.54 存储为 14.539999961853
在调试时,我只能在传递给插入的列表中找到该值 14.54。但是在从 windows 的 SQLite 浏览器应用程序中检查保存的记录时。我看到值已经改变。我使用 sqlite 浏览器手动输入了一个查询,并且值按原样保存(浮点值不改变精度)。例如:
("INSERT INTO MYTABLE (ItemPrice) VALUES (14.54)");
上面的查询执行成功并插入了14.54的浮点数
但在android中使用以下
@Insert
Long[] saveMyTable(final List<MYTABLE> myTable);
MyTable 实体有一个字段为
public float ItemPrice;
插入上述查询时,值发生了变化
我也试过将 DB Schema 中的数据类型更改为 real、float、double。但没有任何帮助。
我正在为演示应用程序使用房间数据库,当时我存储的值与上面定义的值相同。
首先定义 pojo class for table like..
@Entity
public class MyTable {
@PrimaryKey(autoGenerate = true)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private double ItemPrice;
public double getItemPrice() {
return ItemPrice;
}
public void setItemPrice(double itemPrice) {
ItemPrice = itemPrice;
}
}
然后在定义 dao class 之后...
@Dao
public interface MyTableDao {
@Insert
void insertData(MyTable myTable);
}
然后在 table 中定义 db 之后...
@Database(entities = {MyTable.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract MyTableDao getTableDao();
}
然后在主要活动中使用下面的代码后定义数据库名称和版本并插入数据...
public class DbInsert extends AppCompatActivity {
AppDatabase db;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "MyDb").allowMainThreadQueries().build();
MyTable myTable = new MyTable();
myTable.setItemPrice(14.54);
db.getTableDao().insertData(myTable);
}
}
我的代码中有浮动,在数据库模式中它是双精度的(尽管 dosent 意味着任何东西)
但我做了以下工作:
1. 在代码和数据库中使用相同的数据类型(我使用双精度)
2. 存储值时。我四舍五入了我的需要。
public static short COUNTRY_CURRENCY_MAX_DIGITS_AFTER_DECIMAL;//Dynamically set
private static int ROUNDING_MODE = BigDecimal.ROUND_HALF_EVEN;
public double roundedDouble(double doubleValue) {
return new
BigDecimal(doubleValue).setScale(COUNTRY_CURRENCY_MAX_DIGITS_AFTER_DECIMAL,
ROUNDING_MODE).doubleValue();
}
3。根据我在 COUNTRY_CURRENCY_MAX_DIGITS_AFTER_DECIMAL 中设置的值,上面的方法将 return 我一个带 2 位或 3 位小数的双精度值。
4. 最后我将值存储在数据库中。
Ps: 如果没有上述方法,我的浮点数总是转换为默认小数的两倍,我总是得到巨大的价值。
现在对我来说效果很好。
我需要将价格存储在我的房间数据库中。根据使用我的应用程序的国家/地区,我的小数精度可以是 2 位小数或 3 位小数。
在使用android的房间库将float甚至double值存储在sqlite数据库中时,它改变了值。例如: 14.54 存储为 14.539999961853
在调试时,我只能在传递给插入的列表中找到该值 14.54。但是在从 windows 的 SQLite 浏览器应用程序中检查保存的记录时。我看到值已经改变。我使用 sqlite 浏览器手动输入了一个查询,并且值按原样保存(浮点值不改变精度)。例如:
("INSERT INTO MYTABLE (ItemPrice) VALUES (14.54)");
上面的查询执行成功并插入了14.54的浮点数
但在android中使用以下
@Insert
Long[] saveMyTable(final List<MYTABLE> myTable);
MyTable 实体有一个字段为
public float ItemPrice;
插入上述查询时,值发生了变化
我也试过将 DB Schema 中的数据类型更改为 real、float、double。但没有任何帮助。
我正在为演示应用程序使用房间数据库,当时我存储的值与上面定义的值相同。 首先定义 pojo class for table like..
@Entity
public class MyTable {
@PrimaryKey(autoGenerate = true)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private double ItemPrice;
public double getItemPrice() {
return ItemPrice;
}
public void setItemPrice(double itemPrice) {
ItemPrice = itemPrice;
}
}
然后在定义 dao class 之后...
@Dao
public interface MyTableDao {
@Insert
void insertData(MyTable myTable);
}
然后在 table 中定义 db 之后...
@Database(entities = {MyTable.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract MyTableDao getTableDao();
}
然后在主要活动中使用下面的代码后定义数据库名称和版本并插入数据...
public class DbInsert extends AppCompatActivity {
AppDatabase db;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "MyDb").allowMainThreadQueries().build();
MyTable myTable = new MyTable();
myTable.setItemPrice(14.54);
db.getTableDao().insertData(myTable);
}
}
我的代码中有浮动,在数据库模式中它是双精度的(尽管 dosent 意味着任何东西)
但我做了以下工作: 1. 在代码和数据库中使用相同的数据类型(我使用双精度) 2. 存储值时。我四舍五入了我的需要。
public static short COUNTRY_CURRENCY_MAX_DIGITS_AFTER_DECIMAL;//Dynamically set
private static int ROUNDING_MODE = BigDecimal.ROUND_HALF_EVEN;
public double roundedDouble(double doubleValue) {
return new
BigDecimal(doubleValue).setScale(COUNTRY_CURRENCY_MAX_DIGITS_AFTER_DECIMAL,
ROUNDING_MODE).doubleValue();
}
3。根据我在 COUNTRY_CURRENCY_MAX_DIGITS_AFTER_DECIMAL 中设置的值,上面的方法将 return 我一个带 2 位或 3 位小数的双精度值。 4. 最后我将值存储在数据库中。
Ps: 如果没有上述方法,我的浮点数总是转换为默认小数的两倍,我总是得到巨大的价值。
现在对我来说效果很好。