NaN and Infinity in Java
NaN and Infinity in Java
You may be familiar with the fact that you cannot divide an integer with 0 in Java  it yields java.lang.ArithmeticException: / by zero
.
But what happens when we try to do this with floating point numbers.
Let’s give it a try:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int m = 10, n = 0;
System.out.println(m/n);
// Exception: java.lang.ArithmeticException: / by zero
float a = 10.0f, b = 0.0f;
System.out.println(a/b);
// Infinity
Now that is interesting, we didn’t get an exception, but instead, we got something as a result: Infinity
.
If we check out the Float
class, we can see that there are a couple of constants defined in the class:

NaN
 A constant holding a NotaNumber (NaN) value of type float. 
PositiveInfinity
 A constant holding the positive infinity of type float. 
NegativeInfinity
 A constant holding the negative infinity of type float.
What this means is, that some operations in Java may yield values that are not strictly some defined number and behave in a special way.
For example, when we’re diving by 0
, we usually say that the result is Infinity. In maths, this has a special meaning, in terms that
Infinity is not a specific number and has a set of rules defined for it. In Java, we can see that there are two types of infinity: positive and negative.
To get a positive infinity, it means that the result of some operation approaches infinite value, but from the positive side on the number axis  for
example if we divide a positive number by 0, we get infinite results but all of them are positive, thus getting positive infinity.
On the other hand, if we divide a negative number by 0, we also get infinite results, but all of them are negative, so negative infinity.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
float a = 1.0f;
float b = 0.0f;
System.out.println((a/b) == Float.POSITIVE_INFINITY);
// true
// if a is negative
a = 1.0f;
System.out.println((a/b) == Float.POSITIVE_INFINITY);
// false, we should be getting negative infinity
System.out.println((a/b) == Float.NEGATIVE_INFINITY);
// true
But what happens when both of the numbers are 0
? In maths, dividing zero by zero yields an undefined result.
In Java we get NaN
. This is also a constant defined in Float
and Double
classes.
If we try to divide zero by zero, we get something that is not a number, so NaN
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
float a = 0.0f;
float b = 0.0f;
Float c = a/b;
System.out.println(c);
// NaN
System.out.println(c == Float.NaN);
// false
System.out.println(c.isNaN());
// true
Now, this looks weird. Why isn’t the result (c
), which is clearly NaN
, not equal to that constant?
This also comes from maths, where we cannot compare two things that are not numbers. We can only compare something that has
a clear definition or has a clear value. NaN denotes a mathematically undefined value, and as such we cannot compare it (similar to NULL
in SQL
).
What we can do, is to check whether whatever we got is undefined (NotaNumber) by using Float.isNaN()
method.
Some notes on serialization
When serializing special care should be taken to serialize these values properly.
If we do naive serialization, we would get an exception:
1
2
3
4
5
6
7
Gson gson = new Gson();
System.out.println(gson.toJson(new SomeObject(10.0f/0.0f)));
// Throws an exception: java.lang.IllegalArgumentException: Infinity is not a valid double value as per JSON specification. To override this behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.
By setting the serialization of these values, we get the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public static class SomeObject {
private float value;
public SomeObject(float value) {
this.value = value;
}
public float getValue() {
return value;
}
public void setValue(float value) {
this.value = value;
}
}
...
GsonBuilder builder = new GsonBuilder();
builder.serializeSpecialFloatingPointValues();
Gson gson = builder.create();
System.out.println(gson.toJson(new SomeObject(10.0f/0.0f)));
// {"value":Infinity}
System.out.println(gson.toJson(new SomeObject(10.0f/0.0f)));
// {"value":Infinity}
System.out.println(gson.toJson(new SomeObject(0.0f/0.0f)));
// {"value":NaN}
Be careful though, these values may not be recognized by some JSON parsers and you may get some unpredictable results, such as
the values to be converted to String
or getting an error while parsing.