如何在Java中比较两个双值?
Java中两个双值的简单比较会产生一些问题。让我们考虑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
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