【问题标题】:SQLite3 on Android not adding float numbers correctlyAndroid上的SQLite3没有正确添加浮点数
【发布时间】:2016-07-18 15:37:28
【问题描述】:

我在 Android 上的 SQLite3 上运行一些简单的语句时遇到了一些问题。

例如:

SELECT 1234 + 0.001

那应该返回 1234.001,对吧?然而,SQLite 在模拟器 (v21) 和真实设备 (v19) 上都返回 1234。

考虑到 1234 存储在名为 Field1 的列上,类型为 REAL,在 Table1 上,我尝试了以下所有选项:

SELECT Field1 + 0.001 FROM Table1

SELECT (Field1 * 1.000)  + 0.001 FROM Table1

SELECT CAST(Field1 as FLOAT) + 0.001 FROM Table1

SELECT CAST(Field1 as REAL) + 0.001 FROM Table1

SELECT Field1 + 0.001 from Table1

SELECT CAST((Field1 + 0.001) as REAL) FROM Table1

似乎没有任何效果,在每种情况下,我得到的都是 1234 而不是 1234.001。我需要在查询中从 1234 获取 1234.001,但 SQLite3 没有帮助。

我刚刚发现的另一件事:如果“Field1”= 1000 都会给我一个整数。

你能帮我解决这个问题吗?

【问题讨论】:

  • "应该返回 1234.001,对吧?" - 不必要。 1234.001 可能无法表示为浮点数。
  • 您可能正在以 整数 形式检索数据。当你想要一个 float 或一个 double.
  • @CommonsWare 同意,但没有一个 >= 1000 的数字返回为 x.001,如上面的屏幕截图所示。另一方面,任何小于 1000 的数字都会按预期返回。
  • 您的代码中数字的格式究竟如何?
  • 我没有格式化数字。我正在用cursor.getString() 阅读它们,我猜这是罪魁祸首。

标签: android database sqlite


【解决方案1】:

实际上,我发现问题并不像看起来那样。这些数字被视为 x.001,但未显示为这样。在内部,数字以二进制形式正确存储,但并未显示所有小数部分。在将它们转换为文本之后,我能够看到小数部分都在那里。

无论如何,感谢您的时间和回答。

【讨论】:

    【解决方案2】:

    这是一个精度问题,以及数字在计算机中的存储方式或在 sqlite3 中的存储方式。数字以二进制格式存储,这意味着通过将十进制数转换为二进制数,您会失去一些精度(实数)read more here。现在,如果您想像示例中那样添加到 yield 1234.001,您有什么选择?

    A) 将数字存储为字符串。

    您始终可以将值“1234”和“0.001”存储为 VARCHAR,并在 JAVA 代码中将此值解析为 BigDecimals 并在那里执行您的添加。有关解析的更多信息,请查看link。这种方法的缺点是它会在您的数据库中消耗更多的存储空间,并且解析操作也不是那么快。在使用此方法之前,请考虑此缺点是否会对应用程序的性能产生负面影响。

    B) 建立一个 MAXIMUM_PRECISION 并将它们存储为 INTEGER。

    默认情况下,SQLITE3 使用 8 个字节存储 INTEGER。这意味着您可以存储的最大整数约为 10^19。现在,通过存储整数,您不会失去精度;所以我们可以利用这一点。假设您的 MAXIMUM_PRECISION 为 0.001(如您的示例中所示),那么您需要将此数字乘以一千才能得到 1。那么,如果我们不将 1234.001 表示为实数,而是将其表示为 1234001 一个整数呢?这样我们就可以将 int 安全地存储在 sqlite3 中,并确保操作正常工作。在您的代码中,您可以稍后将数字解析为字符串并将其格式化以将其显示给用户,或者您可以将其解析为 BigDecimal 以保持精度。当然,这会将您的最大数量限制在 10^16 的数量级;再次检查您的要求,看看这个技巧是否适用于您的应用程序。请注意,在 sqlit3 中使用了类似的技巧来存储货币而不会丢失精度,更多信息请参见:this link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      相关资源
      最近更新 更多