SQLite查询具有浮点数的where子句是否失败?

时间:2010-07-17 07:07:51

标签: sqlite floating-point where-clause floating-accuracy

我正在基于Android的SQLite数据库中放置一个浮点数,如下所示:

private static final String DATABASE_CREATE = 
    "create table " + DATABASE_TABLE + " ("  
                    + KEY_ID + " integer primary key autoincrement, "
                    + KEY_FLOAT  + " REAL, " + ...
...

content.put(KEY_FLOAT, 37.3f);
db.insert(DATABASE_TABLE, null, content);

当我查询表格时:

Cursor cursor = db.query(false, DATABASE_TABLE, 
      new String[] { KEY_ID, KEY_FLOAT, ... },
      KEY_LATITUDE + "=37.3",
      null, null, null, null, null);

光标返回空白。如果我将float的值更改为37.0它可以正常工作,返回光标中的记录。

我已经测试了一段时间,将数据库列规范从“REAL”更改为“float”等。只要小数点后面有任何小数部分,光标返回空。发生了什么事?

提前致谢!

5 个答案:

答案 0 :(得分:8)

37.0在二进制浮点中是完全可表示的,因此您没有任何正常问题。 37.3 可以完全表示 - 您的查询不匹配,因为数据库中的值不完全是37.3。

选项:

  • 使用基于十进制的数字类型,如果SQLite中存在这样的东西(我会在一分钟内检查)
  • 使您的查询使用容差,例如“LATITUDE> 37.29和LATITUDE< 37.31”。比较二进制浮点值以获得完全相等只是在寻找麻烦,我担心。
编辑:我刚刚检查了the docs,看起来SQLite不支持十进制非整数类型。我将在上面留下这个建议,因为它与其他数据库中的相同问题有关。

编辑:Pascal在很多情况下有效滚动自己的数字类型的解决方案很好。计算出你想要的精度水平,然后相应地进行乘法/除法...所以如果你想要2位小数的精度,你在存储一个值时乘以100,然后在取出它之后除以100。当然,您的查询需要采用“倍增”形式。

答案 1 :(得分:1)

当然,比较浮点值是不公平的。

不管怎么说,我看到SQLite uses 8-byte floating point values(就像DOUBLE),所以37.0被认为等于37.3是奇怪的。除非你为你的例子修改了实际代码中使用的值吗?

您可以将LATITUDE整数存储为十度,自己应用精度,并在读/写时转换值...

答案 2 :(得分:1)

我尝试使用<column> BETWEEN <min> AND <max>并且它有效,宽容LATITUDE > 37.29 AND LATITUDE < 37.31对我不起作用。但是我用这个提示尝试了BETWEEN

我的观察:

  1. 当我有一条记录时,大于(>)不起作用。
  2. 如果有多条记录,则大于(>)工作正常。

答案 3 :(得分:0)

以下内容对我有用:

将Column类型设置为Double,并使用Double数据类型为Java插入行。以某种方式双重工作......

答案 4 :(得分:0)

我遇到了同样的问题。我的Sqlite列是FLOAT类型。我不得不将我的类型为Float的Java变量转换为double,以使比较起作用。