Java 如何确定两个double是否几乎相等

Java 如何确定两个double是否几乎相等,java,math,floating-point,precision,epsilon,Java,Math,Floating Point,Precision,Epsilon,我试图找到一些Java代码来确定两个double是否几乎相等。我在谷歌上搜索了很多东西,找到了我在这里拼凑的零碎东西。我开始忘记的是“相对ε”的使用。这种方法似乎正是我想要的。我不想直接指定ε,但希望使用基于两个参数大小的ε。这是我整理的代码,我需要检查一下它是否正常。(顺便说一句,我的数学知识刚刚够危险的。) 公共类数学 { // http://stackoverflow.com/questions/3728246/what-should-be-the- //执行双值相等比较时的ε值 //UL

我试图找到一些Java代码来确定两个double是否几乎相等。我在谷歌上搜索了很多东西,找到了我在这里拼凑的零碎东西。我开始忘记的是“相对ε”的使用。这种方法似乎正是我想要的。我不想直接指定ε,但希望使用基于两个参数大小的ε。这是我整理的代码,我需要检查一下它是否正常。(顺便说一句,我的数学知识刚刚够危险的。)

公共类数学
{
// http://stackoverflow.com/questions/3728246/what-should-be-the-
//执行双值相等比较时的ε值
//ULP=最后一位的单位
公共静态双通道(双a、双b)
{
返回Math.max(Math.ulp(a),Math.ulp(b));
}
公共静态布尔值近似相等(双a,双b)
{
返回接近相等(a,b,n(a,b));
}
// http://floating-point-gui.de/errors/comparison/
公共静态布尔近似相等(双a、双b、双ε)
{
最终双abs=数学abs(a);
最终双abs=数学abs(b);
最终双差=数学绝对值(a-b);
如果(a==b)
{
//快捷方式,处理无限
返回true;
}
否则如果(a==0 | | b==0 | | absA+absB
我会为此使用一个库,我通常使用的是DoubleMath fro Googles Guava库


if(DoubleMath.fuzzyEquals(a,b,ε)){
//a和b在给定公差范围内相等
}

还有一个模糊比较。

比较两个浮点值
a、b的常用方法是:

if ( Math.abs(a-b) <= epsilon ) do_stuff_if_equal;
 else                       do_stuff_if_different;

但正如我所说,这可能会导致错误的结果。如果您坚持使用
ulp
,那么我将使用
Min
而不是
Max

,您可以从中使用类
org.apache.commons.math3.util.Precision
。例如:

if (Precision.equals(sum, price, 0.009)) {
    // arguments are equal or within the range of allowed error (inclusive)
}

一个ulp可能有点太小了。有没有关于我应该如何增加它的建议?啊,@LouisWasserman,看起来像克劳斯提到的你的东西。我的和其他很多东西一样。但我至少会使用ulp的一个重要常数倍数?尽管坦率地说,没有一个通用的规则,或者每个人都已经在使用它了,而且大多数人更喜欢显式地指定ε。但通常情况下:错误将显著大于一个ulp,并且一个ulp将显著大于
Double.MIN\u NORMAL
。感谢大家。我没有意识到我陷入了怎样的困境。看起来我必须根据每个特定用途定制epsilon。库的fuzzyEqals()需要一个公差参数,这是我使用ulp试图避免的(显然我没有正确执行)。@careysb库要求公差的原因是,正确的公差不仅仅取决于ulp。它取决于考虑到目前为止的计算的舍入误差的预期范围。准确地说,如果任何浮点/双精度是使用计算创建的,则需要一个公差,因为精度可能会丢失。例如
(2f/11*9)*11
为18.000002,与
3f*6
为18.0相比,比较时需要一个公差。
if (Math.abs(a)>=Math.abs(b)) epsilon=1e-30*Math.abs(b);
 else                         epsilon=1e-30*Math.abs(a);
if (Precision.equals(sum, price, 0.009)) {
    // arguments are equal or within the range of allowed error (inclusive)
}