SQLite浮点问题

标签 sqlite floating-point

此查询应返回 0.00,但返回 1.7763568394002505e-15:

SELECT st.id
, Sum(
    CASE sa.Type 
    WHEN 4 THEN sa.quantity * (st.price - st.commission)
    WHEN 5 THEN -sa.quantity * (st.price - st.commission)
    ELSE 0.0 END
) Sales
FROM sales sa
JOIN stock st
  ON sa.stockid = st.id
WHERE st.id = 1
GROUP BY st.id

http://sqlfiddle.com/#!5/cccd8/3

这看起来像是一个经典的浮点计算问题,但我该如何解决它? 我尝试过将各个列转换为 REAL,但没有什么区别。

您可以使用此查询模拟结果:

SELECT 26.3 - 10.52 - 15.78 AS Result

最佳答案

SQLite 的 REAL 不适合货币。 SQlite 不支持 SQL 小数或 SQL 数值数据类型,因此最好的选择是使用整数,并将值存储为分。

CREATE TABLE stock (
  id INTEGER,
  -- Store price and commission as integers, implying that price is in cents,
  -- ($3.20 is stored as 320) and commission is a two-digit percentage (0.57%
  -- is stored as 57).  This is how scaled integers work in general.
  price integer,
  commission integer,
  PRIMARY KEY(id)
);

CREATE TABLE sales (
  id INTEGER,
  stockid INTEGER,
  type INTEGER,
  quantity  INTEGER,
  PRIMARY KEY(id)
);

insert into stock values (1, 320, 57);
insert into sales values (1, 1, 4, 10);
insert into sales values (2, 1, 5, 4);
insert into sales values (3, 1, 5, 6);

来自 SQLfiddle 的此查询正确返回 0。

SELECT st.id
, Sum(
    CASE sa.Type 
    WHEN 4 THEN sa.Quantity * (st.price - st.commission)
    WHEN 5 THEN -sa.Quantity * (st.price - st.commission)
    ELSE 0.0 END
) Sales
FROM sales sa
JOIN stock st
  ON sa.stockid = st.id
WHERE st.id = 1
GROUP BY st.id;
id          Sales
----------  ----------
1           0

转换为更合适的数据类型(不是为 REAL)将隐藏一些问题——甚至可能是特定应用程序中的大多数问题,甚至所有问题。但转换并不能解决这些问题,因为存储的值可能与您真正想要的值不同。

关于SQLite浮点问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29800937/

相关文章:

math - float 学有问题吗?

iphone - NSNumber 和 NSFloat

java - 无法获取要从数据库重新加载的列表项

mysql - Rails 迁移需要不可移植的 SQL

android - 在android中将多个 Intent 从一个 Activity 发送到另一个 Activity

c - 读取带有浮点的文件,计算 C 中的大小、最大值、最小值、平均值、中值和标准差

php - json_encode 返回浮点值,就好像它是

python - 将抓取的内容保存到 Sqlite3 数据库 - 如何?

java - JDBC sqlite 的奇怪错误

c - 数字在 Lua 和 C 中都表现得很奇怪