Skip to content

Rounding Errors

Rounding Errors in java

Definition of the Rounding Problem

Condensing numerous infinite real numbers into a limited set of bits necessitates an estimated depiction. The majority of software retains outcomes from integer operations within a 32 or 64-bit range at most. Irrespective of the chosen bit quantity, the majority of computations involving real numbers will yield values that cannot be precisely manifested within the given bit count. Consequently, the outcome of a floating-point computation frequently requires rounding to align within its finite portrayal. This rounding discrepancy stands as an inherent attribute of floating-point computation.

Hence, when performing computations with floating-point numbers, particularly those involving monetary calculations, it’s essential to address rounding errors within a programming language.

Example 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class Main {
    public static void main(String[] args)
    {
        double a = 0.7;
        double b = 0.9;
        double x = a + 0.1;
        double y = b - 0.1;

        System.out.println("x = " + x);
        System.out.println("y = " + y );
        System.out.println(x == y);
    }
}
StdOut
1
2
3
4
5
Output:

x = 0.7999999999999999
y = 0.8
false
  • Above, the answer is not what we expected reason being the rounding off done by java compiler.

Reason behind round off error

  • Java float and double data types abide by the IEEE floating point 754 specification. This means that numbers are represented in a form like:
1
SIGN FRACTION * 2 ^ EXP 
  • \(0.15625 = (0.00101)_{2}\), which in floating-point format is represented as: \(1.01 * 2^{-3}\)
  • Not all fractions can be represented exactly as a fraction of a power of two.
    • As a simple example, 0.1 = (0.000110011001100110011001100110011001100110011001100110011001… )2 and thus cannot be stored inside a floating-point variable.

Example 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Main {
    public static void main(String args[])
    {
        double a = 1.0;
        double b = 0.10;
        double x = 9 * b;
        a = a - (x);

        // Value of a is expected as 0.1
        System.out.println("a = " + a);
    }
}
StdOut
1
2
3
Output:

a = 0.09999999999999998

How to rectify round off errors?

  1. Round the result: The utilization of the Round() function can mitigate the impact of inaccuracies stemming from floating-point arithmetic storage. Users have the capability to round numbers to the specific decimal places mandated by the calculation’s needs. For instance, in currency-related tasks, it’s common to round to 2 decimal places.
  2. Algorithms and Functions: Employ algorithms that ensure numerical stability or craft custom functions to manage such scenarios. It’s possible to truncate or round uncertain digits (calculating the numeric precision of operations is also an option).
  3. BigDecimal Class: You may use the java.math.BigDecimal class, which is designed to give us accuracy especially in case of big fractional numbers.

Example 3

The following example shows how the error can be removed
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class Main {
    public static void main(String args[])
    {
        double a = 1.0;
        double b = 0.10;
        double x = 9 * b;
        a = a - (x);

    /* We use Math.round() function to round the answer to
         closest long, then we multiply and divide by 1.0 to
         to set the decimal places to 1 place (this can be done
         according to the requirements.*/
        System.out.println("a = " + Math.round(a*1.0)/1.0);
    }
}
StdOut
1
2
3
Output:

0.1
  • Now we get the expected output, without the error.