How to compare two double values in Java?
Basically you shouldn't do exact comparisons, you should do something like this:
double a = 1.000001;
double b = 0.000001;
double c = a-b;
if (Math.abs(c-1.0) <= 0.000001) {...}
Comparison double value
Double.compare
handles the case of NaN and negative zeros differently than ==
. For Double.compare
, -0.0d
is not equal to 0.0d
.
For example the following code:
public static void main(String... args) {
double a = -0.0d;
double b = 0.0d;
if (a == b) {
System.out.println("a == b");
}
if (Double.compare(a, b) == 0) {
System.out.println("Double.compare(a, b) == 0");
}
}
will only print a == b
.
The two operations are thus not equivalent. Using one over the other depend on your requirement.
The exact rule concerning ==
(and !=
) can be found in the JLS, section 15.21.1:
Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard:
If either operand is NaN, then the result of == is false but the result of != is true. Indeed, the test x!=x is true if and only if the value of x is NaN.
Positive zero and negative zero are considered equal.
Otherwise, two distinct floating-point values are considered unequal by the equality operators. In particular, there is one value representing positive infinity and one value representing negative infinity; each compares equal only to itself, and each compares unequal to all other values.
Subject to these considerations for floating-point numbers, the following rules then hold for integer operands or for floating-point operands other than NaN:
- The value produced by the == operator is true if the value of the left-hand operand is equal to the value of the right-hand operand; otherwise, the result is false.
- The value produced by the != operator is true if the value of the left-hand operand is not equal to the value of the right-hand operand; otherwise, the result is false.
Comparing double values for equality in Java.
You could experiment with delta values in the order of 10-15 but you will notice that some calculations give a larger rounding error. Furthermore, the more operations you make the larger will be the accumulated rounding error.
One particularly bad case is if you subtract two almost equal numbers, for example 1.0000000001 - 1.0 and compare the result to 0.0000000001
So there is little hope to find a generic method that would be applicable in all situations. You always have to calculate the accuracy you can expect in a certain application and then consider results equal if they are closer than this accuracy.
For example the output of
public class Main {
public static double delta(double d1, double d2) {
return Math.abs(d1- d2) / Math.max(Math.abs(d1), Math.abs(d2));
}
public static void main(String[] args) {
System.out.println(delta(0.1*0.1, 0.01));
System.out.println(delta(1.0000000001 - 1.0, 0.0000000001));
}
}
is
1.7347234759768068E-16
8.274036411668976E-8
Interval arithmetic can be used to keep track of the accumulated rounding errors. However in practise the error intervals come out too pessimistic, because sometimes rounding errors also cancel each other.
Java comparing double values - bigger number
You can compare doubles with the <
or >
operator.
But you want to get the difference. That can be done simply by taking the absolute value of the subtraction of either one from the other.
Double difference = Math.abs( val1 - val2 );
How to check the larger and smaller value among two double values?
int returnVal = Double.compare(d1, d2);
This does what you want and returns:
The value 0 if d1 is numerically equal to d2; a value less than 0 if d1 is numerically less than d2; and a value greater than 0 if d1 is numerically greater than d2.
Related Topics
What's Java Hybrid - Applet + Application
MySQLsyntaxerrorexception Near "" When Trying to Execute Preparedstatement
How to Unzip Files Programmatically in Android
Service Discovery Failed Exception Using Bluetooth on Android
How to Run a Spring Boot Executable Jar in a Production Environment
How to Use Chef to Update-Alternatives for Java Using Execute
Equivalent of Data Protection API on Linux
Why Is Alternatives Command Used When Installing Java on a Linux MAChine
Can't Run Program with Processbuilder, Runs Fine from Command Line
Multiple Row Selection in Jtable
Illegalargumentexception or Nullpointerexception For a Null Parameter
Firestore - How to Structure a Feed and Follow System
How to Get Android Wifi Scan Results into a List
Understanding Metaspace Line in Jvm Heap Printout
Execute a Linux Terminal Command in Java