If the value is 200.3456
, it should be formatted to 200.34
. If it is 200
, then it should be 200.00
.
Shift the decimal of the given value to the given decimal point by multiplying 10^n. Take the floor of the number and divide the number by 10^n. The final value is the truncated value.
Here's an utility that rounds (instead of truncating) a double to specified number of decimal places.
For example:
round(200.3456, 2); // returns 200.35
public static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); long factor = (long) Math.pow(10, places); value = value * factor; long tmp = Math.round(value); return (double) tmp / factor; }
This breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)
) or large integer part (e.g. round(90080070060.1d, 9)
). Thanks to Sloin for pointing this out.
I've been using the above to round "not-too-big" doubles to 2 or 3 decimal places happily for years (for example to clean up time in seconds for logging purposes: 27.987654321987 -> 27.99). But I guess it's best to avoid it, since more reliable ways are readily available, with cleaner code too.
(Adapted from this answer by Louis Wasserman and this one by Sean Owen.)
public static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); BigDecimal bd = BigDecimal.valueOf(value); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); }
Note that HALF_UP
is the rounding mode "commonly taught at school". Peruse the RoundingMode documentation, if you suspect you need something else such as Bankers’ Rounding.
Of course, if you prefer, you can inline the above into a one-liner:new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
Always remember that floating point representations using float
and double
are inexact. For example, consider these expressions:
999199.1231231235 == 999199.1231231236 // true 1.03 - 0.41 // 0.6200000000000001
For exactness, you want to use BigDecimal. And while at it, use the constructor that takes a String, never the one taking double. For instance, try executing this:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41))); System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Some excellent further reading on the topic:
float
and double
if exact answers are required" in Effective Java (2nd ed) by Joshua BlochIf you wanted String formatting instead of (or in addition to) strictly rounding numbers, see the other answers.
Specifically, note that round(200, 0)
returns 200.0
. If you want to output "200.00", you should first round and then format the result for output (which is perfectly explained in Jesper's answer).
If you just want to print a double
with two digits after the decimal point, use something like this:
double value = 200.3456; System.out.printf("Value: %.2f", value);
If you want to have the result in a String
instead of being printed to the console, use String.format()
with the same arguments:
String result = String.format("%.2f", value);
Or use class DecimalFormat
:
DecimalFormat df = new DecimalFormat("####0.00"); System.out.println("Value: " + df.format(value));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With