Rounding off errors in Java
Last Updated :
05 Jul, 2024
Compacting many infinite real numbers into a finite number of bits requires an approximate representation. Most programs store the result of integer computations at 32 or 64 bits max. Given any fixed number of bits, most calculations with real numbers will produce quantities that cannot be exactly represented using that many bits. Therefore the result of a floating-point calculation must often be rounded to fit back into its finite representation. This rounding error is a characteristic feature of floating-point computation. Therefore, while handling calculations in floating point numbers, (especially if calculations are in terms of money), we need to take care of round-off errors in a programming language. Let’s see an example:
Java
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);
}
}
Output:
x = 0.7999999999999999
y = 0.8
false
Here, the answer is not what we expected reason being the rounding off done by java compiler.
Reason Behind Round Off Error
Float and Double data types implement IEEE floating point 754 specification. This means that numbers are represented in a form like:
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.
Another Example:
java
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);
}
}
Output:
x = 0.7999999999999999
y = 0.8
false
Another example:
Java
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);
}
}
Output:
a = 0.09999999999999998
How to Rectify Round Off Errors?
- Round the result: The Round() function can be used to minimize any effects of floating point arithmetic storage inaccuracy. The user can round numbers to the number of decimal places that is required by the calculation. For example, while working with currency, you would likely round to 2 decimal places.
- Algorithms and Functions: Use numerically stable algorithms or design your own functions to handle such cases. You can truncate/round digits of which you are not sure they are correct (you can calculate numeric precision of operations too)
- BigDecimal Class: You may use the java.math.BigDecimal class, which is designed to give us accuracy especially in case of big fractional numbers. The following program shows how the error can be removed:
Java
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String args[]) {
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.10");
BigDecimal x = b.multiply(new BigDecimal("9"));
a = a.subtract(x);
// Rounding to 1 decimal place
a = a.setScale(1, RoundingMode.HALF_UP);
System.out.println("a = " + a);
}
}
Output:
0.1
Here, a = a.setScale(1, RoundingMode.HALF_UP);
Rounds a
to 1 decimal place using HALF_UP rounding mode. So, using BigDecimal provides more precise control over the arithmetic and rounding operations, which can be particularly useful for financial calculations or other cases where precision is crucial.
Important Note:
Math.round rounds the value to the nearest integer. As 0.10 is closer to 0 than to 1, it gets rounded to 0. After the rounding and division by 1.0, the result is 0.0. So you can notice the difference between the outputs with BigDecimal class and Maths.round function.
Java
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);
}
}
Output:
0.0
Similar Reads
rint() in Java (Rounding to int)
In Java, Math.rint() is an inbuilt method that is used to round off the floating-point argument to an integer value (in floating-point format). Syntax of rint() MethodMath.rint(double n);Parameters The rint() function takes a mandatory single argument value to round. Returns A double value is return
2 min read
DecimalFormat setRoundingMode() method in Java
The setRoundingMode() method is a built-in method of the java.text.DecimalFomrat class in Java and is used to set the RoundingMode to be used with this DecimalFormat instance to round-off the decimal digits. Syntax: public void setRoundingMode(RoundingMode roundingMode) Parameters: The function acce
1 min read
BigDecimal round() Method in Java
The java.math.BigDecimal.round(MathContext m) is an inbuilt method in Java that returns a BigDecimal value rounded according to the MathContext settings. If the precision setting is 0 then no rounding takes place. Syntax: public BigDecimal round(MathContext m) Parameters: The method accepts a single
2 min read
Errors V/s Exceptions In Java
In Java, errors and exceptions are both types of throwable objects, but they represent different types of problems that can occur during the execution of a program. Errors are usually caused by serious problems that are outside the control of the program, such as running out of memory or a system cr
5 min read
DecimalFormat setGroupingSize() method in Java
The setGroupingSize() method is a built-in method of the java.text.DecimalFomrat class in Java and is used to set the grouping size for this DecimalFormat instance or not. The grouping size is the number of integers in each group in the integral part of a decimal number. For example, the grouping si
2 min read
Formatted Output in Java using printf()
Sometimes in programming, it is essential to print the output in a given specified format. Most users are familiar with the printf function in C. Let us discuss how we can Formatting Output with printf() in Java in this article. Formatting Using Java Printf()printf() uses format specifiers for forma
5 min read
StrictMath round() method in Java
round(double num) The round(double num) is the inbuilt method of StrictMath class in Java which is used to obtain the closest long to the given argument num. It returns the rounded value to an integer by adding 1/2, and taking the floor of the obtained result, and after that casting the result to ty
3 min read
String to int in Java
Converting a String to an int in Java can be done using methods provided in the Integer class, such as Integer.parseInt() or Integer.valueOf() methods. Example: The most common method to convert a string to a primitive int is Integer.parseInt(). It throws a NumberFormatException if the string contai
2 min read
Convert String to Double in Java
In this article, we will convert a String to a Double in Java. There are three methods for this conversion from String to Double, as mentioned below in the article. Methods for String-to-Double ConversionDifferent ways for converting a String to a Double are mentioned below: Using the parseDouble()
3 min read
NumberFormat setRoundingMode() method in Java with Examples
The setRoundingMode() method is a built-in method of the java.text.NumberFormat which sets the RoundingMode used in this NumberFormat. The subclasses which handle different rounding modes should override this method. Syntax: public void setRoundingMode(RoundingMode mode) Parameters: The function acc
2 min read