Rounding errors in Java


Series Overview

This article is part of the series. Below are links to all posts in the series:
  1. Floating-Point Arithmetic
  2. Decimal Class in Python
  3. Fraction Class in Python
  4. Rounding Errors in Java

What's inside this article ⌄
  • How to use Python Fraction class
  • Rational numbers Python implementation
  • Convert fractions to decimals Python
  • Python fraction arithmetic operations

Floating Away: Slightly Unstable World of Real Number Computations. Beating Rounding Errors with Java.


We had a discussion about the reasons behind rounding errors and floating-point arithmetic. We solved them in Python with Decimal class and Fraction class.

It’s time to say hello to Java.

Consider this:

double a = 0.7;
double b = 0.9;
double x = a + 0.1;
double y = b - 0.1;

And outputs:

System.out.println("x = " + x);
System.out.println("y = " + y );
System.out.println(x == y);

You might guess the output:

x = 0.7999999999999999
y = 0.8
false

We can fix this using a tolerance-based comparison:

double epsilon = 1e-10;
System.out.println(Math.abs(x - y) < epsilon);

Or by using BigDecimal class:

BigDecimal a = new BigDecimal("0.7");
BigDecimal b = new BigDecimal("0.9");
BigDecimal x = a.add(new BigDecimal("0.1"));
BigDecimal y = b.subtract(new BigDecimal("0.1"));
System.out.println(x.compareTo(y) == 0); // important!

Notice the way we compared x and y. It’s not a direct comparison using =, nor the equals().

Unfortunately, Java does not directly support handling repeating decimals. However, we still can make use of Fraction class of Apache commons-math library:

Fraction fraction1 = new Fraction(3, 4);
Fraction fraction2 = new Fraction(5, 6);
Fraction result = fraction1.add(fraction2);
System.out.println(result); // Output: 19/12

Let’s compare them:

Fraction fraction1 = new Fraction(1, 2);
Fraction fraction2 = new Fraction(2, 4);
System.out.println(fraction1.compareTo(fraction2) == 0); // Output: true