降低 R 中双精度数的精度

Bro*_*ieG 3 floating-point r

我正在寻找一种方法来始终忽略 R 中浮点数之间的微小差异(根据 IEC 60559,这些是双精度浮点数),通过使用基础 R 工具而不使用 C 或 C++。换句话说,我想“舍入”双精度浮点数的有效数部分,这样像这样的东西返回 TRUE 而不是 FALSE:

1.45 - .55 == 2.45 - 1.55
## [1] FALSE
Run Code Online (Sandbox Code Playgroud)

就像是:

round_significand(1.45 - .55, bits=48) == round_significand(2.45 - 1.55, bits=48)
## [1] TRUE
Run Code Online (Sandbox Code Playgroud)

一个简单的方法round不起作用,因为我们需要四舍五入的级别取决于数字的大小。

data.table在内部做一些类似的事情,从?setNumericRounding

计算机无法使用基数 2 精确表示某些浮点数(例如 0.6)。这会导致在连接或分组“数字”类型的列时出现意外行为;即“双倍”,请参见下面的示例。在不希望出现这种情况的情况下,data.table 允许将此类数据四舍五入到大约 11 sf,这在许多情况下是足够的数字。这是通过舍入有效数的最后 2 个字节来实现的。其他可能的值是 1 字节舍入或不舍入(全精度,默认值)。

我正在研究一个 hack 实现,它将所有内容缩放为一个十进制数xfloor(log10(x)) == 1并且四舍五入,例如:

rnd_sig <- function(x, precision=10) {
  exp <- floor(log10(abs(x)))
  round(x * 10 ^ (-exp), precision) / 10 ^ (-exp)
}
Run Code Online (Sandbox Code Playgroud)

但我对浮点数的了解不够,无法确保这是安全的(或何时安全,而不是安全)。

Eri*_*hil 5

对于使用浮点计算的结果可能与精确的数学结果有多大差异,没有通用的答案。通常,计算序列的最终误差范围可以从零到无穷大(并且也可能在有精确数学结果时产生非数字结果,或者在没有定义数学结果时可能产生数字结果)。因此,确定使用什么容差来分类两个计算结果是否相等需要针对特定​​问题的解决方案:必须分析特定问题中涉及的计算和数字,并确定可能误差的界限或权衡特定的优缺点接受不正确的分类。

对导致数值计算的错误的研究是数值分析。这是一个广泛的领域,许多书籍都涉及。不存在简单的答案。

在简单的情况下,可以确定误差的界限并表明这些界限小于已知不同结果之间的差异。换句话说,给定一个理想情况下会产生结果ab但实际上产生a和 的计算b,有可能表明误差上存在一些界限E,使得 | a? b| < E当且仅当a等于b。但是,如果不知道执行了什么计算,并且可能不知道输入值的域是什么,就不可能回答这个问题。