【问题标题】:SQLite query where clause with floating point numbers fails?带有浮点数的 SQLite 查询 where 子句失败?
【发布时间】:2011-03-17 06:46:52
【问题描述】:

我将浮点数放入基于 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”等。只要我在小数点后有任何小数部分,光标就会返回空。怎么回事?

提前致谢!

【问题讨论】:

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


【解决方案1】:

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

选项:

  • 使用基于十进制的数字类型,如果 SQLite 中存在这样的东西(我会检查一下)
  • 让您的查询使用容差,例如“纬度 > 37.29 和纬度

编辑:我刚刚检查了the docs,看起来 SQLite 不支持十进制非整数类型。我会在上面留下这个建议,因为它与其他数据库中的相同问题有关。

编辑:Pascal 的有效滚动您自己的数字类型的解决方案在许多情况下是一个很好的解决方案。计算出您想要的精度级别,并相应地乘/除...因此,如果您想要 2 个小数位的精度,请在存储值时乘以 100,然后在获取值后除以 100。当然,您的查询需要采用“相乘”形式。

【讨论】:

  • 谢谢乔恩。我已经意识到浮点恶魔,但拒绝接受他们可以以如此低的精度输入:我尝试应用 val = (Math.round(val*1000)) / 1000;在进入数据库之前,这是没用的......更多@pascal。
  • @DJC:试着弄清楚 0.1 应该如何用二进制表示......你可以非常接近,但你永远不会完全达到 0.1。跨度>
【解决方案2】:

当然,比较浮点值是否相等是个坏主意。

但是,我看到 SQLite uses 8-byte floating point values(类似于 DOUBLE),所以奇怪的是 37.0 被认为等于 37.3。除非您为示例修改了实际代码中使用的值?

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

【讨论】:

  • 我认为“它适用于 37.0”位已经改变了这两个部分。
  • 谢谢帕斯卡。我已经应用了您的解决方案,将值乘以 1000 并将整数部分放入数据库中,效果很好。不幸的是,我用来填充 UI 列表的 android.widget.SimpleCursorAdapter 当然不知道需要将数字转换回来,所以我要么调整它,要么转向存储字符串。我很想做后者,认为在我要求的精度下,它们在存储和精度上可能与双精度数相当......
  • 哦,是的..仅供参考,问题发生在百分之一..不是十分之一..我简化了这个例子:)
【解决方案3】:

我尝试使用<column> BETWEEN <min> AND <max>,它成功了,容忍LATITUDE > 37.29 AND LATITUDE < 37.31 对我不起作用。但我用这个提示尝试了BETWEEN

我的观察:

  1. 当我有一条记录时,大于 (>) 不起作用。
  2. 如果有多个记录,大于 (>) 可以完美运行。

【讨论】:

    【解决方案4】:

    以下事情对我有用:

    将 Column 类型设置为 Double 并使用 Java 的 Double 数据类型插入行。不知何故 Double 工作......

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题。我的 Sqlite 列的类型为 FLOAT。我必须将 Float 类型的 Java 变量转换为 double 才能进行比较。

      【讨论】:

        猜你喜欢
        • 2012-01-23
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        相关资源
        最近更新 更多