Java: Comparing floating-point numbers

When comparing floating-point numbers (float, double) in Java, we quickly discover that we get roundoff errors. This has to do with the limited precision of Java floating point variables. The following code example shows the problem at hand:

double r = Math.sqrt(2);
double d = r * r - 2;
if (d == 0)
	System.out.println("sqrt(2) squared minus 2 is 0");
else
	System.out.println("sqrt(2) squared minus 2 is not 0 but " + d);

Theoretically, d should be 0, but because we have limited precision (see the documentation on primitive data types) there will be a difference:

sqrt(2) squared minus 2 is not 0 but 4.440892098500626E-16

One possibility to circumvent this problem is to define a constant value (the following example uses EPSILON). We then check if the difference is smaller than that constant value. Since we received a very small number (4.4E-16) above, we can use 1E-14 as the value of our constant:

final double EPSILON = 1E-14;
		
double r = Math.sqrt(2);
double d = r * r - 2;
if (Math.abs(d) <= EPSILON)
	System.out.println("d is approximately 0");
else
	System.out.println("x is not smaller than epsilon!");

Another possibility would be to use the BigDecimal class to represent these values. However, because sqrt(2) is an irrational number, we will have to define a precision and therefore will get the same problem as before, but the difference will be much smaller this time.

Hello world

My name is Simon Krenger, I am a Technical Account Manager (TAM) at Red Hat. I advise our customers in using Kubernetes, Containers, Linux and Open Source.

Elsewhere

  1. GitHub
  2. LinkedIn
  3. GitLab