Infinity is equal to Infinity in Java - java

I wanted to test if infinity is equal to infinity in Java:
Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY
I was surprised by the result when it turned out to be true. My question is how can two infinite values be equal?

Because Double.POSITIVE_INFINITY represents a specific number, so comparing it to itself using == should return true.
This behaviour is specified explicitly in JLS Sec 15.21.1:
Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard:
...
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.

Related

java: double == and Double equals

I am confused on a few things regarding using double.
If i were to initialize 2 doubles with the same literal, would == always evaluate to true? for example, if following outputs true but i don't know if this is by chance:
double a = .1d;
double b = .1d;
System.out.println(a==b);
I get the same result when using Double instead of double:
Double a = .1d;
Double b = .1d;
System.out.println(a.equals(b));
According to Double documentation, equals() return true if doubleValue() are equal.
So the question is, is "==" for double and "equals()" for Double guaranteed to evaluate to true for 2 variables initialized using the same literal?
When would they evaluate to false? Is this when arithmetic operations are involved?
Thanks
In general == is an operator which checks for equality. Object variables are references so it checks for reference or address equality. In the case of primitive data types representing values in the memory that also means that it checks for value equality.
The method equals(~) checks for value or content equality. You do not use it for primitive data types but for Objects.
That is also the case for double and Double. The problem which is arising with doubles is the mismatch of the values induced by rounding errors.
Some arithmetic operations may handle rounding differently so you might get false for value equality even if you think it should be equal.
It should be stated that even if the rounding rules are a bit inconsistent arithmetic operations are deterministic so that inconsistency can be handled.

IsNan() Method Availability

In java we can use the isNan() method for float and double values.
E.g.:
if (!Double.isNaN(0.01)) {
// condition happens
}
if (!Float.isNaN(0.01F)) {
// condition happens
}
I wonder why we can't use it for Integers.
NaN is Not a Number, i.e., an undefined or unrepresentible number, such as the square root of -1.
Integers are always well defined, and Strings just aren't numbers at all, so they are irrelevant for checking against being NaN.
Because String and Integer can't be NaN.
NaN is a special value of floating point numbers, along with others like Infinity; integers and strings don't have such special values, so the functions to check for them would make no sense.
The reason they exist is to represent the results of certain calculations, so that floating point numbers can be used in arbitrary mathematical situations.

is it legal to compare two variables with both Double.positive_infinity values?

in java, is it legal? i need to find points that are collinear with same slope to point of oigin. vertical lines have positive infinity slope. On cell phone, weird typing
From the Java Language Specification
15.20.1 Numerical Comparison Operators <, <=, >, and >=: "All values other than NaN are ordered, with negative infinity less than all finite values, and positive infinity greater than all finite values."
15.21.1 Numerical Equality Operators == and !=: "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."
Totally legal. POSITIVE_INFINITY is a value, after all.
EDIT 2: There used to be some stupid stuff in this post about Double.NaN. If you saw it, disregard it. new Double(1.0 / 0.0).compareTo(Double.POSITIVE_INFINITY) = 0, and POSITIVE_INFINITY equals itself, and that should be enough to handle vertical slopes.

Float.NaN == Float.NaN

Why does this comparison give me 'false'? I looked at the source and Float.NaN is defined as
/**
* A constant holding a Not-a-Number (NaN) value of type
* <code>float</code>. It is equivalent to the value returned by
* <code>Float.intBitsToFloat(0x7fc00000)</code>.
*/
public static final float NaN = 0.0f / 0.0f;
EDIT: surprisingly, if I do this:
System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN)));
it gives me 0. So Float.compare() does think that NaN is equal to itself!
Use Float.isNaN to check for NaN values.
Because Java implements the IEEE-754 floating point standard which guarantees that any comparison against NaN will return false (except != which returns true)
That means, you can't check in your usual ways whether a floating point number is NaN, so you could either reinterpret both numbers as ints and compare them or use the much cleverer solution:
def isNan(val):
return val != val
All I need to say is: Wikipedia About NaN.
It is written quite clearly. The interesting part is that the floating point NaN of the common standard expresses a NaN this way:
s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
The s is the sign (negative or positive), the 1's are the exponent and the x is regarded as a payload.
Looking at the payload a NaN is not equal any NaN and there are rare chances that these information of the payload are interesting for you as a developer (e.g. complex numbers).
Another thing is that in the standard they have signalling and quite NaN. A signalling NaN (sNaN) means an NaN that should raises a reaction like a exception. It should be used to say out loud that you have a problem in your equation. A quiet NaN (qNaN) is a NaN that is silently passed on.
A sNaN that created a signal is converted to a qNaN to not further produce any more signals in subsequent operations. Remember some system define i^0 = 1 as a constant that NaN^0 = 1 holds true. So there are cases where people calculate with NaN.
So in the end I would go with this: qNaN != sNaN but this is internal and is not observable for the user (you cant check that). Mix along the payment and the sign (yes you can have negative and positive NaN) and it appears to me that always return NaN != NaN looks like a much wiser choice that I finally learned to appreciate -> I will never ever complain or wonder about the inequality of NaN again. Praise the folks who were that thoughtful giving us such a good standard!
By the way: Java uses a positive NaN with a payload of 0 (all x are zeros).

comparing float/double values using == operator

The code review tool I use complains with the below when I start comparing two float values using equality operator. What is the correct way and how to do it? Is there a helper function (commons-*) out there which I can reuse?
Description
Cannot compare floating-point values using the equals (==) operator
Explanation
Comparing floating-point values by using either the equality (==) or inequality (!=) operators is not always accurate because of rounding errors.
Recommendation
Compare the two float values to see if they are close in value.
float a;
float b;
if(a==b)
{
..
}
IBM has a recommendation for comparing two floats, using division rather than subtraction - this makes it easier to select an epsilon that works for all ranges of input.
if (abs(a/b - 1) < epsilon)
As for the value of epsilon, I would use 5.96e-08 as given in this Wikipedia table, or perhaps 2x that value.
It wants you to compare them to within the amount of accuracy you need. For example if you require that the first 4 decimal digits of your floats are equal, then you would use:
if(-0.00001 <= a-b && a-b <= 0.00001)
{
..
}
Or:
if(Math.abs(a-b) < 0.00001){ ... }
Where you add the desired precision to the difference of the two numbers and compare it to twice the desired precision.
Whatever you think is more readable. I prefer the first one myself as it clearly shows the precision you are allowing on both sides.
a = 5.43421 and b = 5.434205 will pass the comparison
private static final float EPSILON = <very small positive number>;
if (Math.abs(a-b) < EPSILON)
...
As floating point offers you variable but uncontrollable precision (that is, you can't set the precision other than when you choose between using double and float), you have to pick your own fixed precision for comparisons.
Note that this isn't a true equivalence operator any more, as it isn't transitive. You can easily get a equals b and b equals c but a not equals c.
Edit: also note that if a is negative and b is a very large positive number, the subtraction can overflow and the result will be negative infinity, but the test will still work, as the absolute value of negative infinity is positive infinity, which will be bigger than EPSILON.
Use commons-lang
org.apache.commons.lang.math.NumberUtils#compare
Also commons-math (in your situation more appropriate solution):
http://commons.apache.org/math/apidocs/org/apache/commons/math/util/MathUtils.html#equals(double, double)
The float type is an approximate value - there's an exponent portion and a value portion with finite accuracy.
For example:
System.out.println((0.6 / 0.2) == 3); // false
The risk is that a tiny rounding error can make a comparison false, when mathematically it should be true.
The workaround is to compare floats allowing a minor difference to still be "equal":
static float e = 0.00000000000001f;
if (Math.abs(a - b) < e)
Apache commons-math to the rescue: MathUtils.(double x, double y, int maxUlps)
Returns true if both arguments are equal or within the range of allowed error (inclusive). Two float numbers are considered equal if there are (maxUlps - 1) (or fewer) floating point numbers between them, i.e. two adjacent floating point numbers are considered equal.
Here's the actual code form the Commons Math implementation:
private static final int SGN_MASK_FLOAT = 0x80000000;
public static boolean equals(float x, float y, int maxUlps) {
int xInt = Float.floatToIntBits(x);
int yInt = Float.floatToIntBits(y);
if (xInt < 0)
xInt = SGN_MASK_FLOAT - xInt;
if (yInt < 0)
yInt = SGN_MASK_FLOAT - yInt;
final boolean isEqual = Math.abs(xInt - yInt) <= maxUlps;
return isEqual && !Float.isNaN(x) && !Float.isNaN(y);
}
This gives you the number of floats that can be represented between your two values at the current scale, which should work better than an absolute epsilon.
I took a stab at this based on the way java implements == for doubles. It converts to the IEEE 754 long integer form first and then does a bitwise compare. Double also provides the static doubleToLongBits() to get the integer form. Using bit fiddling you can 'round' the mantissa of the double by adding 1/2 (one bit) and truncating.
In keeping with supercat's observation, the function first tries a simple == comparison and only rounds if that fails. Here is what I came up with some (hopefully) helpful comments.
I did some limited testing, but can't say I've tried all edge cases. Also, I did not test performance. It shouldn't be too bad.
I just realized that this is essentially the same solution as the one offered by Dmitri. Perhaps a bit more concise.
static public boolean nearlyEqual(double lhs, double rhs){
// This rounds to the 6th mantissa bit from the end. So the numbers must have the same sign and exponent and the mantissas (as integers)
// need to be within 32 of each other (bottom 5 bits of 52 bits can be different).
// To allow 'n' bits of difference create an additive value of 1<<(n-1) and a mask of 0xffffffffffffffffL<<n
// e.g. 4 bits are: additive: 0x10L = 0x1L << 4 and mask: 0xffffffffffffffe0L = 0xffffffffffffffffL << 5
//int bitsToIgnore = 5;
//long additive = 1L << (bitsToIgnore - 1);
//long mask = ~0x0L << bitsToIgnore;
//return ((Double.doubleToLongBits(lhs)+additive) & mask) == ((Double.doubleToLongBits(rhs)+additive) & mask);
return lhs==rhs?true:((Double.doubleToLongBits(lhs)+0x10L) & 0xffffffffffffffe0L) == ((Double.doubleToLongBits(rhs)+0x10L) & 0xffffffffffffffe0L);
}
The following modification handles the change in sign case where the value is on either side of 0.
return lhs==rhs?true:((Double.doubleToLongBits(lhs)+0x10L) & 0x7fffffffffffffe0L) == ((Double.doubleToLongBits(rhs)+0x10L) & 0x7fffffffffffffe0L);
There are many cases where one wants to regard two floating-point numbers as equal only if they are absolutely equivalent, and a "delta" comparison would be wrong. For example, if f is a pure function), and one knows that q=f(x) and y===x, then one should know that q=f(y) without having to compute it. Unfortunately the == has two defects in this regard.
If one value is positive zero and the other is negative zero, they will compare as equal even though they are not necessarily equivalent. For example if f(d)=1/d, a=0 and b=-1*a, then a==b but f(a)!=f(b).
If either value is a NaN, the comparison will always yield false even if one value was assigned directly from the other.
Although there are many cases where checking floating-point numbers for exact equivalence is right and proper, I'm not sure about any cases where the actual behavior of == should be considered preferable. Arguably, all tests for equivalence should be done via a function that actually tests equivalence (e.g. by comparing bitwise forms).
First, a few things to note:
The "Standard" way to do this is to choose an constant epsilon, but constant epsilons do not work correctly for all number ranges.
If you want to use a constant epsilon sqrt(EPSILON) the square root of the epsilon from float.h is a generally considered a good value. (this comes from an infamous "orange book" who's name escapes me at the moment).
Floating point division is going to be slow, so you probably want to avoid it for comparisons even if it behaves like picking an epsilon that is custom made for the numbers' magnitudes.
What do you really want to do? something like this:
Compare how many representable floating point numbers the values differ by.
This code comes from this really great article by Bruce Dawson. The article has been since updated here. The main difference is the old article breaks the strict-aliasing rule. (casting floating pointers to int pointer, dereferencing, writing, casting back). While the C/C++ purist will quickly point out the flaw, in practice this works, and I consider the code more readable. However, the new article uses unions and C/C++ gets to keep its dignity. For brevity I give the code that breaks strict aliasing below.
// Usable AlmostEqual function
bool AlmostEqual2sComplement(float A, float B, int maxUlps)
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
int aInt = *(int*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
aInt = 0x80000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
int bInt = *(int*)&B;
if (bInt < 0)
bInt = 0x80000000 - bInt;
int intDiff = abs(aInt - bInt);
if (intDiff <= maxUlps)
return true;
return false;
}
The basic idea in the code above is to first notice that given the IEEE 754 floating point format, {sign-bit, biased-exponent, mantissa}, that the numbers are lexicographically ordered if interpreted as signed magnitude ints. That is the sign bit becomes the sign bit, the and the exponent always completely outranks the mantissa in defining magnitude of the float and because it comes first in determining the magnitude of the number interpreted as an int.
So, we interpret the bit representation of the floating point number as a signed-magnitude int. We then convert the signed-magnitude ints to a two's complement ints by subtracting them from 0x80000000 if the number is negative. Then we just compare the two values as we would any signed two's complement ints, and seeing how many values they differ by. If this amount is less than the threshold you choose for how many representable floats the values may differ by and still be considered equal, then you say that they are "equal." Note that this method correctly lets "equal" numbers differ by larger values for larger magnitude floats, and by smaller values for smaller magnitude floats.

Categories