Java round double value to 2 decimal places Example
1. Introduction
A double variable is used to hold a floating point value, such as 12.578. A decimal place is the position of a digit to the right of a decimal point. The 12.578 with 2 decimal places is represented as 12.57. Java has provided PrintStream, String.format, Formatter, NumberFormat, DecimalFormat, and BigDecimal to format and round a number based on the precision and RoundingMode since version 1.5.
In this example, I will create several junit test classes to demonstrate how to format and round a double value with 2 decimal places.
2. Technologies Used
The example code in this article was built and run using:
- Java 1.8.101
- Eclipse Oxygen
- Junit
- Maven 3.3.9
3. Maven Project
3.1 Dependency
Add Junit to the pom.xml.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>java-round-double</groupId> <artifactId>java-round-double</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
3.2 Constants
In this step, I will create a TEST_DOUBLES variable to hold a double[] array and a TWO_DECIMAL_PLACES_STRING_FORMAT variable to hold a String for 2 decimal places format which will be used in PrintStream, String, and Formatter classes.
TestConstants.java
package org.jcg.zheng;
public class TestConstants {
public static double[] TEST_DOUBLES = { -123.345, 0.4, 0.446, 124, 124.56679 };
public static final String TWO_DECIMAL_PLACES_STRING_FORMAT = "%.2f";
}
3.3 PrintStream
PrintStream provides printf and format methods. Here are the methods’ signatures:
PrintStream printf(Locale l, String format, Object... args) A convenience method to write a formatted string to this output stream using the specified format string and arguments. PrintStream printf(String format, Object... args) A convenience method to write a formatted string to this output stream using the specified format string and arguments. PrintStream format(Locale l, String format, Object... args) Writes a formatted string to this output stream using the specified format string and arguments. PrintStream format(String format, Object... args) Writes a formatted string to this output stream using the specified format string and arguments.
In this step, I will create a junit test class to format a double value with 2 decimal places. The String format syntax for 2 decimal places is "%.2f" which is defined in the TestConstants class.
PrintStreamTest.java
package org.jcg.zheng;
import org.junit.Test;
public class PrintSteamTest {
@Test
public void test_printf() {
for (double testDouble : TestConstants.TEST_DOUBLES) {
System.out.print("Original double:" + testDouble);
System.out.printf(", Rounded=" + TestConstants.TWO_DECIMAL_PLACES_STRING_FORMAT + "\n",
testDouble);
}
}
@Test
public void test_format() {
for (double testDouble : TestConstants.TEST_DOUBLES) {
System.out.format("Rounded=" + TestConstants.TWO_DECIMAL_PLACES_STRING_FORMAT + "\n",
testDouble);
}
}
}
3.4 String.format
The String class provides two static format methods. Here are the methods’ signatures:
static String format(Locale l, String format, Object... args) Returns a formatted string using the specified locale, format string, and arguments. static String format(String format, Object... args) Returns a formatted string using the specified format string and arguments.
In this step, I will create a junit test class to format a double value with 2 decimal places and make sure the original double value is equal to the rounded value within 2 decimal places.
StringFormatTest.java
package org.jcg.zheng;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class StringFormatTest {
@Test
public void test_print_String_format() {
for (double testDouble : TestConstants.TEST_DOUBLES) {
String doubleTwoDecimal = String.format(TestConstants.TWO_DECIMAL_PLACES_STRING_FORMAT,
testDouble);
double roundedValue = Double.valueOf(doubleTwoDecimal);
assertEquals(testDouble, roundedValue, 0.01);
System.out.println("Rounded=" + doubleTwoDecimal);
}
}
}
3.5 Formatter
The Formatter class provides the format method. Here are the methods’ signatures:
Formatter format(Locale l, String format, Object... args) Writes a formatted string to this object's destination using the specified locale, format string, and arguments. Formatter format(String format, Object... args) Writes a formatted string to this object's destination using the specified format string and arguments.
In this step, I will create a junit test class to format a double value with 2 decimal places.
FormatterTest.java
package org.jcg.zheng;
import static org.junit.Assert.assertEquals;
import java.util.Formatter;
import org.junit.Test;
public class FormaterTest {
@Test
public void test_Formatter() {
for (double testDouble : TestConstants.TEST_DOUBLES) {
Formatter fmt = new Formatter();
fmt.format(TestConstants.TWO_DECIMAL_PLACES_STRING_FORMAT, testDouble);
double roundedValue = Double.valueOf(fmt.toString());
assertEquals(testDouble, roundedValue, 0.01);
System.out.println("Rounded=" + roundedValue);
fmt.close();
}
}
}
3.6 NumberFormat
The NumberFormat class provides the format method. Here are the methods’ signatures:
String format(double number) Specialization of format. abstract StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) Specialization of format.
In this step, I will create a junit test class to format a double value with 2 decimal places with Java 8 steam API.
NumberFormatTest.java
package org.jcg.zheng;
import static org.junit.Assert.assertEquals;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;
import org.junit.Test;
public class NumberFormatTest {
private DoubleStream doubleStream = DoubleStream.of(-123.345, 0.4, 0.446, 124, 124.56679);
@Test
public void test_NumberFormat_format() {
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
doubleStream.forEach(testDouble -> {
Stream.of(RoundingMode.values()).forEach(roundingMode -> {
nf.setRoundingMode(roundingMode);
System.out.print("Original double:" + testDouble);
try {
double roundedDouble = Double.valueOf(nf.format(testDouble));
assertEquals(testDouble, roundedDouble, 0.01);
System.out.println(
" " + roundingMode.name() + ", formatted double:" + roundedDouble);
} catch (Exception e) {
System.out.println(
" " + roundingMode.name() + "Caught exception" + e.getMessage());
}
});
});
}
}
3.7 DecimalFormat
The DecimalFormat class provides a format method. Here is the method’s signature:
StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) Formats a double to produce a string.
In this step, I will create a junit test class to format a double value with 2 decimal places.
Note:
- 0 – prints a digit if provided, otherwise prints 0.
- # – prints a digit if provided, otherwise prints nothing.
DecimalFormatTest.java
package org.jcg.zheng;
import static org.junit.Assert.assertEquals;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import org.junit.Test;
public class DecimalFormatTest {
private final String TWO_DECIMAL_FORMAT_PAD_ZERO_AFTER = "#.00";
private final String TWO_DECIMAL_FORMAT_PAD_ZERO_BEFORE = "0.##";
private final String TWO_DECIMAL_FORMAT_NOT_PAD = "#.##";
private final String TWO_DECIMAL_FORMAT_PAD_ZERO = "0.00";
public String[] TWO_PLACES_FORMATS = { TWO_DECIMAL_FORMAT_PAD_ZERO_AFTER,
TWO_DECIMAL_FORMAT_PAD_ZERO_BEFORE, TWO_DECIMAL_FORMAT_NOT_PAD,
TWO_DECIMAL_FORMAT_PAD_ZERO };
@Test
public void test_DecimalFormat() {
for (double testDouble : TestConstants.TEST_DOUBLES) {
for (String decimalFormat : TWO_PLACES_FORMATS) {
DecimalFormat df = new DecimalFormat(decimalFormat);
for (RoundingMode rm : RoundingMode.values()) {
if (!RoundingMode.UNNECESSARY.equals(rm)) {
df.setRoundingMode(rm);
double roundedValue = Double.valueOf(df.format(testDouble));
assertEquals(testDouble, roundedValue, 0.01);
printDouble(testDouble, df.format(testDouble), rm, decimalFormat);
}
}
}
}
}
private void printDouble(double testDouble, String rounded, RoundingMode rm,
String decimalFormat) {
System.out.println("Original=" + testDouble + " Rounded with \"" + decimalFormat + "\" "
+ rm.name() + " =" + rounded);
}
}
3.8 BigDecimal.round
The BigDecimal class provides a round method to round a double value based on a MathContext. Here is the method’s signature:
BigDecimal round(MathContext mc) Returns a BigDecimal rounded according to the MathContext settings.
In this step, I will create a junit test class to format a double value with 2 decimal places.
DecimalRoundTest.java
package org.jcg.zheng;
import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.junit.Test;
public class BigDecimalRoundTest {
private static final double TEST_DOUBLE = 0.56679;
@Test
public void test_round_2() {
BigDecimal bigDec = BigDecimal.valueOf(TEST_DOUBLE);
System.out.println("original double: " + TEST_DOUBLE);
for (RoundingMode rm : RoundingMode.values()) {
System.out.print("\tRoundingMode=" + rm.name());
try {
double roundValue = bigDec.setScale(2, rm).doubleValue();
assertEquals(TEST_DOUBLE, roundValue, 0.01);
System.out.println("\t With 2 decimal places: " + roundValue);
} catch (ArithmeticException ae) {
System.out.println("Caught exception for " + rm.name());
}
}
}
@Test
public void test_round_2and3() {
BigDecimal bigDec = BigDecimal.valueOf(TEST_DOUBLE);
double round2 = bigDec.setScale(2, BigDecimal.ROUND_CEILING).doubleValue();
double round3 = bigDec.setScale(3, BigDecimal.ROUND_CEILING).doubleValue();
assertEquals(0.57, round2, 0.01);
assertEquals(0.567, round3, 0.001);
}
}
4. Demo
I will execute the Junit tests and capture the results.
4.1 PrintStream
In this step, I will execute junit tests and capture the output.
Junit output
Original double:-123.345, Rounded=-123.35 Original double:0.4, Rounded=0.40 Original double:0.446, Rounded=0.45 Original double:124.0, Rounded=124.00 Original double:124.56679, Rounded=124.57
4.2 String.format
In this step, I will execute junit tests and capture the output.
Junit output
Rounded=-123.35 Rounded=0.40 Rounded=0.45 Rounded=124.00 Rounded=124.57
4.3 Formatter
In this step, I will execute junit tests and capture the output.
Junit output
Rounded=-123.35 Rounded=0.4 Rounded=0.45 Rounded=124.0 Rounded=124.57
4.4 NumberFormat
In this step, I will execute junit tests and capture the output.
Junit output
Original double:-123.345 UP, formatted double:-123.35 Original double:-123.345 DOWN, formatted double:-123.34 Original double:-123.345 CEILING, formatted double:-123.34 Original double:-123.345 FLOOR, formatted double:-123.35 Original double:-123.345 HALF_UP, formatted double:-123.34 Original double:-123.345 HALF_DOWN, formatted double:-123.34 Original double:-123.345 HALF_EVEN, formatted double:-123.34 Original double:-123.345 UNNECESSARYCaught exceptionRounding needed with the rounding mode being set to RoundingMode.UNNECESSARY Original double:0.4 UP, formatted double:0.4 Original double:0.4 DOWN, formatted double:0.4 Original double:0.4 CEILING, formatted double:0.4 Original double:0.4 FLOOR, formatted double:0.4 Original double:0.4 HALF_UP, formatted double:0.4 Original double:0.4 HALF_DOWN, formatted double:0.4 Original double:0.4 HALF_EVEN, formatted double:0.4 Original double:0.4 UNNECESSARY, formatted double:0.4 Original double:0.446 UP, formatted double:0.45 Original double:0.446 DOWN, formatted double:0.44 Original double:0.446 CEILING, formatted double:0.45 Original double:0.446 FLOOR, formatted double:0.44 Original double:0.446 HALF_UP, formatted double:0.45 Original double:0.446 HALF_DOWN, formatted double:0.45 Original double:0.446 HALF_EVEN, formatted double:0.45 Original double:0.446 UNNECESSARYCaught exceptionRounding needed with the rounding mode being set to RoundingMode.UNNECESSARY Original double:124.0 UP, formatted double:124.0 Original double:124.0 DOWN, formatted double:124.0 Original double:124.0 CEILING, formatted double:124.0 Original double:124.0 FLOOR, formatted double:124.0 Original double:124.0 HALF_UP, formatted double:124.0 Original double:124.0 HALF_DOWN, formatted double:124.0 Original double:124.0 HALF_EVEN, formatted double:124.0 Original double:124.0 UNNECESSARY, formatted double:124.0 Original double:124.56679 UP, formatted double:124.57 Original double:124.56679 DOWN, formatted double:124.56 Original double:124.56679 CEILING, formatted double:124.57 Original double:124.56679 FLOOR, formatted double:124.56 Original double:124.56679 HALF_UP, formatted double:124.57 Original double:124.56679 HALF_DOWN, formatted double:124.57 Original double:124.56679 HALF_EVEN, formatted double:124.57 Original double:124.56679 UNNECESSARYCaught exceptionRounding needed with the rounding mode being set to RoundingMode.UNNECESSARY
4.5 DecimalFormat
In this step, I will execute junit tests and capture the output.
Junit output
Original=-123.345 Rounded with "#.00" UP =-123.35 Original=-123.345 Rounded with "#.00" DOWN =-123.34 Original=-123.345 Rounded with "#.00" CEILING =-123.34 Original=-123.345 Rounded with "#.00" FLOOR =-123.35 Original=-123.345 Rounded with "#.00" HALF_UP =-123.34 Original=-123.345 Rounded with "#.00" HALF_DOWN =-123.34 Original=-123.345 Rounded with "#.00" HALF_EVEN =-123.34 Original=-123.345 Rounded with "0.##" UP =-123.35 Original=-123.345 Rounded with "0.##" DOWN =-123.34 Original=-123.345 Rounded with "0.##" CEILING =-123.34 Original=-123.345 Rounded with "0.##" FLOOR =-123.35 Original=-123.345 Rounded with "0.##" HALF_UP =-123.34 Original=-123.345 Rounded with "0.##" HALF_DOWN =-123.34 Original=-123.345 Rounded with "0.##" HALF_EVEN =-123.34 Original=-123.345 Rounded with "#.##" UP =-123.35 Original=-123.345 Rounded with "#.##" DOWN =-123.34 Original=-123.345 Rounded with "#.##" CEILING =-123.34 Original=-123.345 Rounded with "#.##" FLOOR =-123.35 Original=-123.345 Rounded with "#.##" HALF_UP =-123.34 Original=-123.345 Rounded with "#.##" HALF_DOWN =-123.34 Original=-123.345 Rounded with "#.##" HALF_EVEN =-123.34 Original=-123.345 Rounded with "0.00" UP =-123.35 Original=-123.345 Rounded with "0.00" DOWN =-123.34 Original=-123.345 Rounded with "0.00" CEILING =-123.34 Original=-123.345 Rounded with "0.00" FLOOR =-123.35 Original=-123.345 Rounded with "0.00" HALF_UP =-123.34 Original=-123.345 Rounded with "0.00" HALF_DOWN =-123.34 Original=-123.345 Rounded with "0.00" HALF_EVEN =-123.34 Original=0.4 Rounded with "#.00" UP =.40 Original=0.4 Rounded with "#.00" DOWN =.40 Original=0.4 Rounded with "#.00" CEILING =.40 Original=0.4 Rounded with "#.00" FLOOR =.40 Original=0.4 Rounded with "#.00" HALF_UP =.40 Original=0.4 Rounded with "#.00" HALF_DOWN =.40 Original=0.4 Rounded with "#.00" HALF_EVEN =.40 Original=0.4 Rounded with "0.##" UP =0.4 Original=0.4 Rounded with "0.##" DOWN =0.4 Original=0.4 Rounded with "0.##" CEILING =0.4 Original=0.4 Rounded with "0.##" FLOOR =0.4 Original=0.4 Rounded with "0.##" HALF_UP =0.4 Original=0.4 Rounded with "0.##" HALF_DOWN =0.4 Original=0.4 Rounded with "0.##" HALF_EVEN =0.4 Original=0.4 Rounded with "#.##" UP =0.4 Original=0.4 Rounded with "#.##" DOWN =0.4 Original=0.4 Rounded with "#.##" CEILING =0.4 Original=0.4 Rounded with "#.##" FLOOR =0.4 Original=0.4 Rounded with "#.##" HALF_UP =0.4 Original=0.4 Rounded with "#.##" HALF_DOWN =0.4 Original=0.4 Rounded with "#.##" HALF_EVEN =0.4 Original=0.4 Rounded with "0.00" UP =0.40 Original=0.4 Rounded with "0.00" DOWN =0.40 Original=0.4 Rounded with "0.00" CEILING =0.40 Original=0.4 Rounded with "0.00" FLOOR =0.40 Original=0.4 Rounded with "0.00" HALF_UP =0.40 Original=0.4 Rounded with "0.00" HALF_DOWN =0.40 Original=0.4 Rounded with "0.00" HALF_EVEN =0.40 Original=0.446 Rounded with "#.00" UP =.45 Original=0.446 Rounded with "#.00" DOWN =.44 Original=0.446 Rounded with "#.00" CEILING =.45 Original=0.446 Rounded with "#.00" FLOOR =.44 Original=0.446 Rounded with "#.00" HALF_UP =.45 Original=0.446 Rounded with "#.00" HALF_DOWN =.45 Original=0.446 Rounded with "#.00" HALF_EVEN =.45 Original=0.446 Rounded with "0.##" UP =0.45 Original=0.446 Rounded with "0.##" DOWN =0.44 Original=0.446 Rounded with "0.##" CEILING =0.45 Original=0.446 Rounded with "0.##" FLOOR =0.44 Original=0.446 Rounded with "0.##" HALF_UP =0.45 Original=0.446 Rounded with "0.##" HALF_DOWN =0.45 Original=0.446 Rounded with "0.##" HALF_EVEN =0.45 Original=0.446 Rounded with "#.##" UP =0.45 Original=0.446 Rounded with "#.##" DOWN =0.44 Original=0.446 Rounded with "#.##" CEILING =0.45 Original=0.446 Rounded with "#.##" FLOOR =0.44 Original=0.446 Rounded with "#.##" HALF_UP =0.45 Original=0.446 Rounded with "#.##" HALF_DOWN =0.45 Original=0.446 Rounded with "#.##" HALF_EVEN =0.45 Original=0.446 Rounded with "0.00" UP =0.45 Original=0.446 Rounded with "0.00" DOWN =0.44 Original=0.446 Rounded with "0.00" CEILING =0.45 Original=0.446 Rounded with "0.00" FLOOR =0.44 Original=0.446 Rounded with "0.00" HALF_UP =0.45 Original=0.446 Rounded with "0.00" HALF_DOWN =0.45 Original=0.446 Rounded with "0.00" HALF_EVEN =0.45 Original=124.0 Rounded with "#.00" UP =124.00 Original=124.0 Rounded with "#.00" DOWN =124.00 Original=124.0 Rounded with "#.00" CEILING =124.00 Original=124.0 Rounded with "#.00" FLOOR =124.00 Original=124.0 Rounded with "#.00" HALF_UP =124.00 Original=124.0 Rounded with "#.00" HALF_DOWN =124.00 Original=124.0 Rounded with "#.00" HALF_EVEN =124.00 Original=124.0 Rounded with "0.##" UP =124 Original=124.0 Rounded with "0.##" DOWN =124 Original=124.0 Rounded with "0.##" CEILING =124 Original=124.0 Rounded with "0.##" FLOOR =124 Original=124.0 Rounded with "0.##" HALF_UP =124 Original=124.0 Rounded with "0.##" HALF_DOWN =124 Original=124.0 Rounded with "0.##" HALF_EVEN =124 Original=124.0 Rounded with "#.##" UP =124 Original=124.0 Rounded with "#.##" DOWN =124 Original=124.0 Rounded with "#.##" CEILING =124 Original=124.0 Rounded with "#.##" FLOOR =124 Original=124.0 Rounded with "#.##" HALF_UP =124 Original=124.0 Rounded with "#.##" HALF_DOWN =124 Original=124.0 Rounded with "#.##" HALF_EVEN =124 Original=124.0 Rounded with "0.00" UP =124.00 Original=124.0 Rounded with "0.00" DOWN =124.00 Original=124.0 Rounded with "0.00" CEILING =124.00 Original=124.0 Rounded with "0.00" FLOOR =124.00 Original=124.0 Rounded with "0.00" HALF_UP =124.00 Original=124.0 Rounded with "0.00" HALF_DOWN =124.00 Original=124.0 Rounded with "0.00" HALF_EVEN =124.00 Original=124.56679 Rounded with "#.00" UP =124.57 Original=124.56679 Rounded with "#.00" DOWN =124.56 Original=124.56679 Rounded with "#.00" CEILING =124.57 Original=124.56679 Rounded with "#.00" FLOOR =124.56 Original=124.56679 Rounded with "#.00" HALF_UP =124.57 Original=124.56679 Rounded with "#.00" HALF_DOWN =124.57 Original=124.56679 Rounded with "#.00" HALF_EVEN =124.57 Original=124.56679 Rounded with "0.##" UP =124.57 Original=124.56679 Rounded with "0.##" DOWN =124.56 Original=124.56679 Rounded with "0.##" CEILING =124.57 Original=124.56679 Rounded with "0.##" FLOOR =124.56 Original=124.56679 Rounded with "0.##" HALF_UP =124.57 Original=124.56679 Rounded with "0.##" HALF_DOWN =124.57 Original=124.56679 Rounded with "0.##" HALF_EVEN =124.57 Original=124.56679 Rounded with "#.##" UP =124.57 Original=124.56679 Rounded with "#.##" DOWN =124.56 Original=124.56679 Rounded with "#.##" CEILING =124.57 Original=124.56679 Rounded with "#.##" FLOOR =124.56 Original=124.56679 Rounded with "#.##" HALF_UP =124.57 Original=124.56679 Rounded with "#.##" HALF_DOWN =124.57 Original=124.56679 Rounded with "#.##" HALF_EVEN =124.57 Original=124.56679 Rounded with "0.00" UP =124.57 Original=124.56679 Rounded with "0.00" DOWN =124.56 Original=124.56679 Rounded with "0.00" CEILING =124.57 Original=124.56679 Rounded with "0.00" FLOOR =124.56 Original=124.56679 Rounded with "0.00" HALF_UP =124.57 Original=124.56679 Rounded with "0.00" HALF_DOWN =124.57 Original=124.56679 Rounded with "0.00" HALF_EVEN =124.57
4.6 BigDecimal.round
In this step, I will execute junit tests and capture the output.
Junit output
original double: 0.56679 RoundingMode=UP With 2 decimal places: 0.57 RoundingMode=DOWN With 2 decimal places: 0.56 RoundingMode=CEILING With 2 decimal places: 0.57 RoundingMode=FLOOR With 2 decimal places: 0.56 RoundingMode=HALF_UP With 2 decimal places: 0.57 RoundingMode=HALF_DOWN With 2 decimal places: 0.57 RoundingMode=HALF_EVEN With 2 decimal places: 0.57 RoundingMode=UNNECESSARYCaught exception for UNNECESSARY
5. Java round double value to 2 decimal places – Summary
In this example, I demonstrated how to round a double value with 2 decimal places via PrintStream, String.format, Formatter, NumberFormat, DecimalFormat, and BigDecimal.
PrintStream, String.format, and Formatter use the same String format syntax to format without knowing the RoundingMode. NumberFormat, DecimalFormat, and BigDecimal round the number with a specific RoundingMode.
6. Download the Source Code
This example consists of a Maven project to round a double value with 2 decimal places.
You can download the full source code of this example here: Java round double value to 2 decimal places Example

