You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XTS中的Decimal值为何不相等?如何正确进行比较?

解决XTS对象中Decimal值比较的精度问题

我来帮你捋清楚这个问题——其实这不是XTS的特性,核心原因是浮点数(哪怕你用了Decimal类型)的精度存储问题,尤其是像1.9这种无法用二进制浮点数精确表示的数值。

问题根源

你觉得1.9×3=5.7完全没有舍入误差,但实际在计算机里:

  • 1.9这个数本身,在默认的二进制浮点数(比如R里的numeric类型)中是无法精确存储的,它会被存成一个极其接近1.9的近似值。
  • 当你把这个近似值乘以3之后,得到的结果会接近5.7,但和你手动输入的5.7(同样是一个近似值)并不完全相等,这时候直接用==比较自然会失败。
  • 整数能正常比较,是因为整数可以被二进制浮点数精确存储,不存在近似问题。

正确的比较方法

这里给你几个实用的解决方案:

1. 用近似比较代替精确相等

永远不要直接用==比较浮点数(包括Decimal类型),改用R内置的all.equal()函数,它会自动处理合理的精度差异:

library(xts)
# 假设你的XTS对象是这样创建的(以decimal包为例)
library(decimal)
t <- xts(x = decimal(c(1.9)), order.by = as.Date("2018-01-03"))

# 用all.equal进行近似比较
all.equal(t["2018-01-03"], decimal(5.7))
# 如果是默认numeric类型,可以自定义容忍度(比如1e-10)
all.equal(t["2018-01-03"], 5.7, tolerance = 1e-10)

all.equal()会返回TRUE如果两个值在合理的精度范围内匹配,默认的容忍度已经能覆盖绝大多数日常场景。

2. 确保Decimal类型被正确保留

如果你确实想用Decimal类型做精确比较,先检查XTS对象有没有偷偷把类型转成了numeric:

# 检查列的类型
class(t[,1])

如果输出是numeric而不是decimal,说明XTS在创建时自动转换了类型(XTS对非numeric类型的支持有限)。这种情况下,要么改用tibble/data.table结合日期索引来维护Decimal类型,要么还是回到近似比较的方案更省心。

3. 用Decimal运算生成预期值

不要手动输入5.7,而是用原始的Decimal值计算预期结果,这样能保证两边的精度一致:

# 用Decimal运算生成预期值
expected_value <- decimal(1.9) * 3
# 再进行比较
all.equal(t["2018-01-03"], expected_value)

这种方式能避免手动输入带来的二次精度误差,比较结果会更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:49:12