在 SQLite 中存储浮点值会更改 Room DB 中的小数精度

Posted

技术标签:

【中文标题】在 SQLite 中存储浮点值会更改 Room DB 中的小数精度【英文标题】:Storing a float value in SQLite changes the decimal precision in Room DB 【发布时间】:2018-08-06 18:14:14 【问题描述】:

我需要将价格存储在我的房间数据库中。我可以有 2 位小数或 3 位小数的小数精度,具体取决于我的应用在哪个国家/地区使用。

在使用android的房间库在sqlite数据库中存储float甚至double值时,它会更改值。例如: 14.54 存储为 14.539999961853

在调试时,我只能在传递给插入的列表中找到该值是 14.54。但是在从 Windows 的 SQLite 浏览器应用程序中检查保存的记录时。我看到价值观发生了变化。我已经使用 sqlite 浏览器手动输入了一个查询,并且该值按原样保存(浮点值而不更改精度)。例如:

("INSERT INTO MYTABLE (ItemPrice) VALUES (14.54)");

以上查询执行成功,插入14.54的float

但在android中使用以下

@Insert 
Long[] saveMyTable(final List<MYTABLE> myTable);

MyTable 实体有一个字段为

public float ItemPrice;

在插入上述查询时,值发生了变化

我还尝试将 DB Schema 中的数据类型更改为 real、float、double。但没有任何帮助。

【问题讨论】:

不可能!!我在我的房间模型类中使用浮点数,它工作正常。您在插入数据时是否使用浮点数转换了您的值? 不是手动的。我使用的是浮点数,但是在将浮点数(在代码中)保存为双精度(在 DB 中)时,它会自动转换值并存储巨大的小数。我下面提到的答案解决了它。 【参考方案1】:

我正在使用房间数据库作为演示应用程序,当时我存储的值与上面定义的值相同。 首先为表定义 pojo 类..

@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 类之后...

@Dao
public interface MyTableDao 
@Insert
void insertData(MyTable myTable);


然后在表中定义数据库后...

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


【讨论】:

【参考方案2】:

我的代码中有浮点数,而在 db 模式中它是双倍的(尽管剂量意味着什么)

但我做了以下事情: 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 中设置的值,上述方法将返回带有 2 位或 3 位小数的双精度值。 4. 最后我将值存储在数据库中。

Ps:如果没有上述方法,我的浮点数总是用默认小数转换成双倍,我总是得到巨大的价值。

现在它对我来说很好用。

【讨论】:

以上是关于在 SQLite 中存储浮点值会更改 Room DB 中的小数精度的主要内容,如果未能解决你的问题,请参考以下文章

变量更改值

Jetpack Room

Jetpack Room

SQLite教程04-SQLite数据类型

Room----Android数据库(SQLite)

JSONKit在从iphone中的Web服务解码JSON对象时更改浮点值