You need to enable JavaScript to run this app. SQLite内存库中文本转Decimal求和结果异常 预期0却得极小非零值
优惠活动
大模型
产品
解决方案
定价
更多

SQLite内存库中文本转Decimal求和结果异常 预期0却得极小非零值

问题原因解析

核心差异来自SQLite对DECIMAL类型的实现逻辑

  • SQLite 没有内置的精确定点DECIMAL数据类型,你写的CAST(xxx AS DECIMAL)语句在SQLite执行时,会直接把值转换为*8字节IEEE754双精度浮点数(REAL类型)*存储和运算,根本不会像SQL Server那样生成固定精度的精确十进制数值。
  • 这类双精度浮点数本身是二进制近似存储结构:像0.09、999999.99这类两位小数的十进制值,是无法被二进制浮点数完全精确表示的,每个值在存储时都会带上极其微小的固有偏差。
  • 累加过程中,这些单值的微小偏差不会完全抵消:你样本里10组正的999999.99、10组负的-999999.99,加上一对0.09和-0.09,正负数的主体值虽然可以完全对冲,但每个值附带的浮点存储偏差累加后,就会凑出-1.31316482687716e-09这种1e-9级别的极小残差。
  • 这个偏差不是你的文本解析逻辑、过滤条件写错导致的,也不是数据本身有问题。SQL Server在执行同逻辑查询时,会使用定点十进制规则做精确运算,不存在浮点近似误差,所以能输出精确的0结果。

可落地的解决方法

  • 如果需要得到无偏差的精确求和结果,不要依赖SQLite的浮点转换逻辑,可以在SQL层做整数缩放运算绕开浮点误差:把替换逗号后的数值放大100倍转成整数累加,最后再把结果缩回原数量级,示例写法是:
SELECT SUM(CAST(REPLACE(FE1, ',', '.') * 100 AS INTEGER)) / 100.0
FROM DRC
WHERE DTS >= '2021-04-21T17:04:44+02:00' 
  AND DTS < '2021-04-21T17:20:09+02:00' 
  AND (DTS IN (SELECT DTS FROM NYN WHERE CNC = '0')
    OR DTS IN (SELECT DTS FROM ESN WHERE CNC = '0')
    OR DTS IN (SELECT DTS FROM SZN WHERE CNC = '0')
    OR DTS IN (SELECT DTS FROM VBN WHERE CNC = '0')
  )
  • 也可以把文本值的解析、累加逻辑放到应用层完成,使用应用侧的精确十进制类型做计算,从根源上避免浮点近似的干扰。

内容的提问来源于stack exchange,提问作者slt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 17:45:03