How to test if a double is zero? - java

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)

Related

java - what is the fastest way(method) to test if double is an int and how to decide?

how can i tell which method is better to use for my situation or faster?.
for example:-
public boolean isSquareNumber(){
double nd = Math.sqrt(num); // num is a class member variable.
if(nd == Math.floor(nd))
{
return true;
} else {
return false;
}
}
and this method
public boolean isSquareNumber(){
double nd = Math.sqrt(num);
if(nd == (int)Math.sqrt(nd))
{
return true;
} else {
return false;
}
}
Math.floor() and Math.sqrt().
both were exactly the same for this situation but how do i decide which is faster?.
Thank you for your time <3.
The fastest way to test if a double value is an integer will be this:
double d = ...
if (d == ((long) d)) {
// It is an integer
}
Note that is (theoretically) possible for sqrt(someValue) to produce an double value that is indistinguishable from an integer value, even though the true square root of someValue is not an integer. As the javadoc states:
Otherwise, the result is the double value closest to the true mathematical square root of the argument value.
So you could get a case where the "closest" double value corresponds to an integer, even though the actual square root is irrational.
The other point of contention is whether Math.floor is actually correct.
On the one hand, the narrowing cast and Math.floor are different:
narrowing uses IEE 754 "rounding towards zero" mode
Math.floor() returns "the largest (closest to positive infinity) floating-point value that less than or equal to the argument and is equal to a mathematical integer". In other words, it rounds towards negative infinity.
On the other hand, if we are testing a double value that is known to be non-negative1, then rounding towards zero and towards negative infinity are the same thing.
1 - Is this the case for Math.sqrt()? Strictly no, since sqrt(-0.0) is defined to return -0.0 ... per the javadoc. However, -0.0 should be treated as +0.0 for the purposes of rounding.

Cast from float to double

Can someone please explain me why this code doesn‘t compile:
boolean r = (boolean) 0;
Why does this one compile?
double z = (float) 2.0_0+0___2;
I don‘t understand the Alphabet in which the numbers after float are written.
The first one doesn't compile because you simply can't cast a number to a boolean. A boolean is true or false.
The second one just uses underscores, which can be used to separate numbers like 2_000_000 for improved readability. In this case they're used to decrease readability, as is the cast to float (a double cast to float and assigned to double doesn't do anything in this particular case).
The latter case seems to be designed for confusion, as there are several pitfalls. If we remove the unnecessary underscores we get 2.00+02 which adds a literal double with an octal 02. This is still basically just 2+2, but if the octal value were 0___10 you'd get a result of z = 10. Then you have the cast to float which could affect the final result, as 64 bits are forced to 32 bits and then back to 64 bits. This could make the end result less precise than without the cast.
In some languages, like PHP or Javascript 0 is falsy, that is, not false, but evaluated as a boolean value, it will be false. In C, 0 is false. These are possible reasons for your expectation. However, in Java you cannot convert a number to a boolean. If you want to have a truey-ish evaluation, you can implement helper methods, like:
public class LooselyTyped {
public boolean toBoolean(int input) {
return input != 0;
}
public boolean toBoolean(Object input) {
return (input != null) && (!input.equals(""));
}
}
and then:
boolean lt = LooselyTyped.toBoolean(yourvariable);

Difference between Math.min() and if condition

What way is the best to get minimum number and which improved the performance or both are same as performance wise?
One way to get the min distance between two number :
double minDistance = Double.MAX_VALUE;
double distance = coordinate1.distnaceTo(coordinate2);
if(distnace < minDistance ) {
minDistance = distance;
}
Another way to get the min distance between two number :
double minDistance = Double.MAX_VALUE;
double minDistance = Math.min(coordinate1.distnaceTo(coordinate2), minDistance);
If you are dealing with positive numbers, not equal to NaN, -0.0 or 0.0, then there shouldn't be much difference.
The following from the Math.min source code in Java 8 highlights the following differences:
If either value is NaN, then the result is NaN. Unlike the numerical comparison operators, this method considers negative zero to be
strictly smaller than positive zero. If one argument is positive zero
and the other is negative zero, the result is negative zero.
So Math.min may be slightly less efficient since it checks for NaN and -0.0 vs 0.0, but it is arguably more readable - you need to consider firstly whether the special cases are applicable or not, and then readability vs (ever so slight) performance difference after that.
Personally I would use Math.min, but that's my own opinion.
Java Math#min(double, double) does the following:
Returns the smaller of two double values. That is, the result is the value closer to negative infinity.
If the arguments have the same value, the result is that same value.
If either value is NaN, then the result is NaN.
If one argument is positive zero and the other is negative zero, the result is negative zero.
Take a look at the source:
public static double min(double a, double b) {
if (a != a) return a; // a is NaN
if ((a == 0.0d) && (b == 0.0d) && (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) {
return b;
}
return (a <= b) ? a : b;
}
And here is your implementation:
if(distnace < minDistance ) {
....
}
So, yes your code is a little bit faster than Math.min() as it checks some additional condition, NaN, zero or negativity whereas your if-else doesn't care any of those.

Can doubles or BigDecimal overflow?

Java 8 gave us Math.addExact() for integers but not decimals.
Is it possible for double and BigDecimal to overflow? Judging by Double.MAX_VALUE and How to get biggest BigDecimal value I'd say the answer is yes.
As such, why don't we have Math.addExact() for those types as well? What's the most maintainable way to check this ourselves?
double overflows to Infinity and -Infinity, it doesn't wrap around. BigDecimal doesn't overflow, period, it is only limited by the amount of memory in your computer. See: How to get biggest BigDecimal value
The only difference between + and .addExact is that it attempts to detect if overflow has occurred and throws an Exception instead of wraps. Here's the source code:
public static int addExact(int x, int y) {
int r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
If you want to check that an overflow has occurred, in one sense it's simpler to do it with double anyway because you can simply check for Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY; in the case of int and long, it's a slightly more complicated matter because it isn't always one fixed value, but in another, these could be inputs (e.g. Infinity + 10 = Infinity and you probably don't want to throw an exception in this case).
For all these reasons (and we haven't even mentioned NaN yet), this is probably why such an addExact method doesn't exist in the JDK. Of course, you can always add your own implementation to a utility class in your own application.
The reason you do not need a addExact function for floating point digits is because instead of wrapping around, it overflows to Double.Infinity.
Consequently you can very easily check at the end of the operation whether it overflowed or not. Since Double.POSITIVE_INFINITY + Double.NEGATIVE_INFINITY is NaN you also have to check for NaN in case of more complicated expressions.
This is not only faster but also easier to read. Instead of having Math.addExact(Math.addExact(x, y), z) to add 3 doubles together, you can instead write:
double result = x + y + z;
if (Double.isInfinite(result) || Double.isNan(result)) throw ArithmeticException("overflow");
BigDecimal on the other hand will indeed overflow and throw a corresponding exception in that case as well - this is very unlikely to ever happen in practice though.
For double, please check the other answers.
BigDecimal has the addExact() protection already built in. Many arithmetic operation methods (e.g. multiply) of BigDecimal contain a check on the scale of the result:
private int checkScale(long val) {
int asInt = (int)val;
if (asInt != val) {
asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
BigInteger b;
if (intCompact != 0 &&
((b = intVal) == null || b.signum() != 0))
throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
}
return asInt;
}

How to represent NaN in array of numbers?

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.

Categories

Resources