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