如何在Java中比较两个双值?

如何在Java中比较两个双值?,java,Java,Java中两个双值的简单比较会产生一些问题。让我们考虑java中的以下简单代码片段。 package doublecomparision; final public class DoubleComparision { public static void main(String[] args) { double a = 1.000001; double b = 0.000001; System.out.println("\n

Java中两个双值的简单比较会产生一些问题。让我们考虑java中的以下简单代码片段。
package doublecomparision;

final public class DoubleComparision 
{
    public static void main(String[] args) 
    {
        double a = 1.000001;
        double b = 0.000001;

        System.out.println("\n"+((a-b)==1.0));
    }
}


上面的代码似乎返回表达式
((a-b)=1.0)的计算值
true
,但它不返回。相反,它返回
false
,因为此表达式的计算结果为
0.9999999999999999
,实际预期为
1.0
,不等于
1.0
,因此,条件的计算结果为布尔值
false
。克服这种情况的最佳建议方法是什么?

请使用java.math.BigDecimal,而不是对十进制算术使用双精度。这将产生预期的结果


参考一下这个

基本上你不应该做精确的比较,你应该这样做:

double a = 1.000001;
double b = 0.000001;
double c = a-b;
if (Math.abs(c-1.0) <= 0.000001) {...}
双a=1.000001;
双b=0.000001;
双c=a-b;
if(Math.abs(c-1.0)可以使用;它比较两个指定的双精度值。

int mid=10;
        int mid = 10;
        for (double j = 2 * mid; j >= 0; j = j - 0.1) {
            if (j == mid) {
                System.out.println("Never happens"); // is NOT printed
            }

            if (Double.compare(j, mid) == 0) {
                System.out.println("No way!"); // is NOT printed
            }

            if (Math.abs(j - mid) < 1e-6) {
                System.out.println("Ha!"); // printed
            }
        }
        System.out.println("Gotcha!");
对于(双j=2*mid;j>=0;j=j-0.1){ 如果(j==mid){ System.out.println(“从不发生”);//未打印 } 如果(双比较(j,mid)==0){ System.out.println(“不行!”;//未打印 } if(数学abs(j-mid)<1e-6){ System.out.println(“Ha!”);//已打印 } } System.out.println(“明白了!”);
只需使用Double.compare()方法来比较两个值。
Double.比较((d1,d2)==0)

double d1 = 0.0;
double d2 = 0.0;

System.out.println(Double.compare((d1,d2) == 0))  // true
返回

  • -1:“a”在数字上小于“b”

  • 0:“a”等于“b”

  • 1:“a”大于“b”


    • 考虑一下这一行代码:

      Math.abs(firstDouble - secondDouble) < Double.MIN_NORMAL
      
      Math.abs(firstDouble-secondDouble)
      它返回firstDouble是否等于secondDouble。我不确定这是否适用于您的具体情况(正如Kevin指出的,对浮点执行任何数学运算都可能导致不精确的结果)然而,我在比较两个实际上相等的double时遇到了困难,而使用“compareTo”方法并没有返回0


      我只是把这个放在这里,以防有人需要比较它们是否真的相等,而不仅仅是相似。

      这是因为double和float不能表示每一个数值。它们实际上使用近似值来表示数值。问题的标题非常误导。问题的作者实际上在问,如何对double typ进行精确的数学运算。答案是你不能。如果必须的话,可以使用BigDecimalr或类似的方法。这些方法至少在理论上具有无限的精度。这是一篇好文章:BigDecimal有时不是一个可行的解决方案。但海报特别询问了比较double的问题。你可能想看看double的比较方法。检查此链接:但如果使用Double.compare,请注意(1)如果d1和d2都表示Double.NaN,则该方法返回true,即使Double.NaN==Double.NaN的值为false;以及(2)如果d1表示+0.0,而d2表示-0.0,或者反之亦然,则该方法返回值false,即使+0.0==-0.0的值为true。此定义允许哈希表正常运行。这也可以使用
      Math.ulp()
      而不是像
      0.000001
      这样的固定错误(尽管有这么明显的错误)我不相信Double.compare本身就解决了海报上提出的问题。你仍然需要abs和阈值
      compare
      的优点是它解释了
      NaN
      -0.0
      -问题肯定解决不了,我相信它确实解决了,但请仔细看看:你仍然需要abs和threshold.Double.compare没有任何神奇的作用;如果查看javadoc,它会返回“如果d1在数值上等于d2,则返回值0;如果d1在数值上小于d2,则返回值小于0;如果d1在数值上大于d2,则返回值大于0。”,有效地做d1==d2在这种情况下,已经有多篇关于此的帖子。在SO中搜索更好。这也会返回问题数据的
      false
      。给定数据的错误是关于
      1e-16
      MIN_NORMAL
      是关于
      2e-308
      -远离{{也许你想使用
      Math.ulp()
      }您不能对双I的基元类型调用方法,即使可以(或使用
      double.valueOf()
      ),它肯定会返回数字不同的结果,我的意思不仅仅是将
      a
      b
      进行比较,而是将
      a-b
      1.0
      Math.abs(firstDouble - secondDouble) < Double.MIN_NORMAL