The question says it all. I have an array of doubles and am doing something with them.
double expectedOutput[] = { 6.38792, 12.91079, 14.33333, 13.44517,
12.34539, 12.05397, 8.34061, 2.07900, -2.01999, -5.47802,
-8.21610, -9.26719, -11.02378 };
Ideally, i would test to see if
6.38792 == 6.38792 and end up with a 'pass'
Under certain conditions, i end up with the situation like
6.38792 != NaN
Knowing that this is a valid case sometimes, how can i represent NaN in my code?
I either need to include NaNs into my array of expected elements or somehow figure out that result is Not A Number
I am using Java
In Java, you can get NaN by using
Double.NaN
So you can just put this into your array.
If your question is how to check if something is NaN, you can call
Double.isNan(/* ... value ... */);
You'll have to test for it explicitly, since NaN != NaN, you can't just include it in your array. You have to use Double.isNaN(x).
double d = 0.0/0.0;
if(Double.isNan(d)){
// Double d is not a number.
}
Alternatively:
double d = Double.Nan;
if(Double.isNan(d)){
// Double d is not a number.
}
Since in many languages NaN is not equal to itself (and in Java also), you should handle it as a specific case. Use Float.NaN or Double.NaN to reference NaN. Use Float.isNaN or Double.isNaN to check if a specific value is NaN.
This is a case where Double objects actually are more useful than primitive doubles.
// auto-boxes them all to Double objects
Collection<Double> expectedOutput =
Arrays.asList(6.38792, 12.91079, 14.33333, 13.44517, 12.34539,
12.05397, 8.34061, 2.07900, -2.01999, -5.47802,
-8.21610, -9.26719, -11.02378, Double.NaN );
// maybe fill into HashSet for more efficient lookup?
// later:
double d = Double.NaN;
if(expectedOutput.contains(d)) {
System.out.println("found");
}
The reason is that Double.equals in fact implements the reflexivity condition of the equals contract, meaning that Double.valueOf(Double.NaN).equals(Double.valueOf(Double.NaN)) gives true, contrary to Double.NaN != Double.NaN.
Related
I know that because of binary double representation, comparison for equality of two doubles is not quite safe. But I need to perform some computation like this:
double a;
//initializing
if(a != 0){ // <----------- HERE
double b = 2 / a;
//do other computation
}
throw new RuntimeException();
So, comparison of doubles is not safe, but I definitely do not want to to devide by 0. What to do in this case?
I'd use BigDecimal but its performance is not quite acceptable.
Well, if your issue is dividing by zero, the good news is that you can do what you have since if the value isn't actually 0, you can divide by it, even if it's really, really small.
You can use a range comparison, comparing it to the lowest value you want to allow, e.g. a >= 0.0000000000001 or similar (if it's always going to be positive).
What about using the Static method compare of the Double class wrapper??
double a = 0.0;
// initializing
if (Double.compare(a, 0.0) != 0) {
}
I have some code like this:
class Foo {
public double x;
}
void test() {
Foo foo = new Foo();
// Is this a valid way to test for zero? 'x' hasn't been set to anything yet.
if (foo.x == 0) {
}
foo.x = 0.0;
// Will the same test be valid?
if (foo.x == 0) {
}
}
I basically want to avoid a divide-by-zero exception in the future.
Thanks
Numeric primitives in class scope are initialized to zero when not explicitly initialized.
Numeric primitives in local scope (variables in methods) must be explicitly initialized.
If you are only worried about division by zero exceptions, checking that your double is not exactly zero works great.
if(value != 0)
//divide by value is safe when value is not exactly zero.
Otherwise when checking if a floating point value like double or float is 0, an error threshold is used to detect if the value is near 0, but not quite 0.
public boolean isZero(double value, double threshold){
return value >= -threshold && value <= threshold;
}
Yes; all primitive numeric types default to 0.
However, calculations involving floating-point types (double and float) can be imprecise, so it's usually better to check whether it's close to 0:
if (Math.abs(foo.x) < 2 * Double.MIN_VALUE)
You need to pick a margin of error, which is not simple.
In Java, 0 is the same as 0.0, and doubles default to 0 (though many advise always setting them explicitly for improved readability).
I have checked and foo.x == 0 and foo.x == 0.0 are both true if foo.x is zero
Yes, it's a valid test although there's an implicit conversion from int to double. For clarity/simplicity you should use (foo.x == 0.0) to test. That will hinder NAN errors/division by zero, but the double value can in some cases be very very very close to 0, but not exactly zero, and then the test will fail (I'm talking about in general now, not your code). Division by that will give huge numbers.
If this has anything to do with money, do not use float or double, instead use BigDecimal.
The safest way would be bitwise OR ing your double with 0.
Look at this XORing two doubles in Java
Basically you should do if ((Double.doubleToRawLongBits(foo.x) | 0 ) ) (if it is really 0)
Lately I've written a project in Java and noticed a very strange feature with double/Double implementation. The double type in Java has two 0's, i.e. 0.0 and -0.0 (signed zero's). The strange thing is that:
0.0 == -0.0
evaluates to true, but:
new Double(0.0).equals(new Double(-0.0))
evaluates to false. Does anyone know the reason behind this?
It is all explained in the javadoc:
Note that in most cases, for two instances of class Double, d1 and d2, the value of d1.equals(d2) is true if and only if
d1.doubleValue() == d2.doubleValue()
also has the value true. However, there are two exceptions:
If d1 and d2 both represent Double.NaN, then the equals method returns true, even though Double.NaN==Double.NaN has the value false.
If d1 represents +0.0 while d2 represents -0.0, or vice versa, the equal test has the value false, even though +0.0==-0.0 has the value true.
This definition allows hash tables to operate properly.
Now you might ask why 0.0 == -0.0 is true. In fact they are not strictly identical. For example:
Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false
is false. However, the JLS requires ("in accordance with the rules of the IEEE 754 standard") that:
Positive zero and negative zero are considered equal.
hence 0.0 == -0.0 is true.
It important to undertand the use of signed zero in the Double class. (Loads of experienced Java programmers don't).
The short answer is that (by definition) "-0.0 is less than 0.0" in all the methods provided by the Double class (that is, equals(), compare(), compareTo(), etc)
Double allows all floating point numbers to be "totally ordered on a number line".
Primitives behave the way a user will think of things (a real world definition) ... 0d = -0d
The following snippets illustrate the behaviour ...
final double d1 = 0d, d2 = -0d;
System.out.println(d1 == d2); //prints ... true
System.out.println(d1 < d2); //prints ... false
System.out.println(d2 < d1); //prints ... false
System.out.println(Double.compare(d1, d2)); //prints ... 1
System.out.println(Double.compare(d2, d1)); //prints ... -1
There are other posts that are relevant and nicely explain the background ...
1: Why do floating-point numbers have signed zeros?
2: Why is Java's Double.compare(double, double) implemented the way it is?
And a word of caution ...
If you don't know that, in the Double class, "-0.0 is less than 0.0", you may get caught out when using methods like equals() and compare() and compareTo() from Double in logic tests. For example, look at ...
final double d3 = -0d; // try this code with d3 = 0d; for comparison
if (d3 < 0d) {
System.out.println("Pay 1 million pounds penalty");
} else {
System.out.println("Good things happen"); // this line prints
}
if (Double.compare(d3, 0d) < 0) { //use Double.compare(d3, -0d) to match the above behaviour
System.out.println("Pay 1 million pounds penalty"); // this line prints
} else {
System.out.println("Good things happen");
}
and for equals you might try ... new Double(d3).equals(0d) || new Double(d3).equals(-0d)
By using == statement you are comparing values. With equals your are comparing objects.
This question already has answers here:
In Java, what does NaN mean?
(11 answers)
Closed 5 years ago.
I have a double[] and it has a value which is NaN. When I add up the array's elements, the NaN makes the result NaN too.
How did it happen? How can I prevent this NaN from being added to the rest of my array?
NaN stands for Not-a-Number. It can arise in a variety of ways, for example as a result of 0./0., sqrt(-1), or as the result of a calculation involving other NaNs.
The easiest way to check whether v is a NaN is by using Double.isNaN(v):
public static double sum(double arr[]) {
double sum = 0.0;
for (double val : arr) {
if (!Double.isNaN(val)) {
sum += val;
}
}
return sum;
}
edit: #Stephen C makes a good point in the comments: before deciding to ignore that NaN, it would be prudent to understand where it came from. It could be that it is the result of a bug elsewhere in your code, and by blindly ignoring the NaN you could simply be masking the bug instead of fixing it.
NaN stands for "Not a Number", so "Not A Number" + 10 = "Not a Number"
You might want to consider debuggin your app to find what's in the double array :)
how can i prevent that this NaN not bein added to the rest of my double[]
This way:
double[] array = something;
double sum = 0;
for (int i = 0; i < array.length; i++) {
if (!Double.isNaN(array[i])) {
sum += array[i];
}
}
RTFM:
Javadoc for NaN
public static final double NaN
A constant holding a Not-a-Number (NaN) value of type double. It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L).
And relevant section of the JVM spec says any operation involving a NaN is also a NaN (a bit like a null in SQL)
You can't just ignore the NaN, it's an indicator of a problem with you're program. You need to find out what is causing the NaN and fix that.
NaN - Not a Number
btw try :
double[] array = new double[10];
String result = StringUtils.join(array);
System.out.println(result+ " BATMAN !");
Java isn't my strong suit, but in other languages this comes from assigning a value from a string. Try this:
parseDouble
public static double parseDouble(String s)
throws NumberFormatException
Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.
Parameters:
s - the string to be parsed.
Returns:
the double value represented by the string argument.
Throws:
NumberFormatException - if the string does not contain a parsable double.
Since:
1.2
See Also:
valueOf(String)
Taken from here.
I was looking at the implementation of compare(double, double) in the Java standard library (6). It reads:
public static int compare(double d1, double d2) {
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
What are the merits of this implementation?
edit: "Merits" was a (very) bad choice of words. I wanted to know how this works.
The explanation is in the comments in the code. Java has double values for both 0.0 and -0.0, as well as "not a number" (NaN). You can't use simple == operator for these values. Take a peek into the doubleToLongBits() source and at the Javadoc for the Double.equals() method:
Note that in most cases, for two
instances of class Double, d1 and d2,
the value of d1.equals(d2) is true if
and only if
d1.doubleValue() == d2.doubleValue()
also has the value true. However,
there are two exceptions:
If d1 and d2 both represent Double.NaN, then the equals method returns true, even
though Double.NaN == Double.NaN has the value false.
If d1 represents +0.0 while d2 represents -0.0, or vice versa, the equal test has the value false, even though +0.0 == -0.0 has the value true.
This definition allows hash tables to operate properly.
#Shoover's answer is correct (read it!), but there is a bit more to it than this.
As the javadoc for Double::equals states:
"This definition allows hash tables to operate properly."
Suppose that the Java designers had decided to implement equals(...) and compare(...) with the same semantics as == on the wrapped double instances. This would mean that equals() would always return false for a wrapped NaN. Now consider what would happen if you tried to use a wrapped NaN in a Map or Collection.
List<Double> l = new ArrayList<Double>();
l.add(Double.NaN);
if (l.contains(Double.NaN)) {
// this wont be executed.
}
Map<Object,String> m = new HashMap<Object,String>();
m.put(Double.NaN, "Hi mum");
if (m.get(Double.NaN) != null) {
// this wont be executed.
}
Doesn't make a lot of sense does it!
Other anomalies would exist because -0.0 and +0.0 have different bit patterns but are equal according to ==.
So the Java designers decided (rightly IMO) on the more complicated (but more intuitive) definition for these Double methods that we have today.
The merit is that it's the simplest code that fulfills the specification.
One common characteristic of rookie programmers is to overvalue reading source code and undervalue reading specifications. In this case, the spec:
http://java.sun.com/javase/6/docs/api/java/lang/Double.html#compareTo%28java.lang.Double%29
... makes the behavior and the reason for the behavior (consistency with equals()) perfectly clear.
That implementation allows a real number to be defined as < NaN, and -0.0 as < 0.0.