If the value is 200.3456
, it should be formatted to 200.34
.
If it is 200
, then it should be 200.00
.
-
2As Monn commented (in an answer), do you actually want 200.34 or 200.35 for 200.3456? As you accepted my answer, I guess you did want **rounding** (+ maybe also formatting) and not just **truncating**. But could you perhaps still clarify what you meant? – Jonik May 11 '10 at 08:58
-
4Obviously not an answer to your question, but anyone reading this question should seriously consider why they really need to be using a Double instead of a BigDecimal. – Bill K Jul 23 '13 at 20:04
-
16@BillK I would assume because a BigDecimal takes a BigPerformanceHit. – JohnMerlino Jul 06 '14 at 21:23
-
6This is not a duplicate. The other question wants a String as a result. This one wants a double and the solution is different. – Bogdan Calmac Feb 18 '16 at 15:42
-
5Not a duplicate; formatting & rounding are two *completely* different things. – AStopher Mar 28 '16 at 18:44
-
It is a duplicate, because the only solution is to lose the floating point and use a decimal radix. – user207421 Mar 23 '19 at 22:28
13 Answers
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
Original version; watch out with this
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.
So, use this instead
(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()
And in every case
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:
- Item 48: "Avoid
float
anddouble
if exact answers are required" in Effective Java (2nd ed) by Joshua Bloch - What Every Programmer Should Know About Floating-Point Arithmetic
If 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).
-
41Once again, downvotes are more useful with a comment. (Note that the question *is* ambiguous and my answer makes it clear that it doesn't tackle every interpretation of the question.) – Jonik May 11 '10 at 09:05
-
see the [answer](http://stackoverflow.com/questions/7548841/round-a-double-to-3-significant-figures/7553827#7553827) for why `tmp/factor` sort of thing might fail – pinkpanther Jun 06 '13 at 18:25
-
3Read the first comment on that answer too. Obviously, if you're dealing with exact (e.g. monetary) values, you [should **not** be using double in the first place](http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency). (In such case, [use BigDecimal](http://stackoverflow.com/questions/285680/representing-monetary-values-in-java).) – Jonik Jul 04 '13 at 06:44
-
Man if I do round(3.375d, 19+) it returns 1.0, it works only up to 18 places precision, so the method should throw IllegalArgumentException if places > 18 – lisak Jul 04 '13 at 08:40
-
@Sloin: You are right. While useful for many typical purposes, it does break down badly with high number of decimal places / large integer part. Thanks for pointing it out. I've updated the answer. – Jonik Jul 15 '13 at 23:04
-
2Thanks, this looks rock solid, btw this one liner more elegant : return new BigDecimal(value).setScale(places, BigDecimal.ROUND_HALF_UP).doubleValue(); – lisak Oct 11 '13 at 13:52
-
That mite help in rounding the double ,but i am afraid it will not properly format the value.In case u want exatly 2 digits this will not help always .For eg: '50.1' will give u 50.1 (even if u set the scale as 2).... i think instead of taking the doubleValue() ,we should be using the toString(). – pablogeorge Jun 03 '14 at 09:25
-
As it says in the end, this answer does not deal with formatting a double as string. The other answers (e.g. [by Jesper](http://stackoverflow.com/a/2808587/56285)) cover that. – Jonik Jun 03 '14 at 10:43
-
3@lisak: In what situation does rounding to 18 digits make sense? Isn't the point of *rounding* to create a simplified representation? OK, maybe when calculating interest on a large loan .. but hopefully anyone doing financial calculations already knows to use `BigDecimal` instead of `double` to represent their values, so wouldn't be looking for this solution. To abuse a method, and then call it `shitty`, is unprofessional. Nevertheless, it is good to highlight the limits of a solution. – ToolmakerSteve Aug 28 '15 at 00:25
-
-
@MahanteshMAmbi: What do you mean? `round(0.5, 1)` returns 0.5 and `round(0.5, 0)` gives 1, which is correct `HALF_UP` rounding. – Jonik Jan 14 '16 at 23:15
-
This doesn't format, only *rounds* the `double`. Formatting is an entirely different matter altogether.. – AStopher Mar 28 '16 at 18:45
-
And what about NaNs and infinities? The should stay to be NaN and infinities. – plastique Jul 18 '16 at 13:27
-
-
Item 48: "Avoid float and double if exact answers are required" is completely misleading and should read "Avoid float and double if exact _fixed digit notation_ answers are required". Otherwise the rounded version could be much worse than the full-form float ... – YoYo Mar 17 '17 at 19:36
-
This technique fails for most values. See my answer in the duplicate for empirical proof. – user207421 Mar 23 '19 at 22:29
-
-
Do NOT use the "Original answer" and NOT the "So, use this instead". Converting the result back to a double will never work reliably, because the result likely does not have an accurate binary representation. Also, all the answers given here are ignoring the accuracy of the original floating point values, which will inevitably lead to problems. See the "What Every Programmer Should Know About Floating-Point Arithmetic" in the answer. – fishinear Oct 25 '19 at 16:41
-
@JaimeMontoya Use the DecimalFormat class as described in other answers. – fishinear Oct 25 '19 at 16:43
-
@fishinear Thank you. What I used was `formatter.setMaximumFractionDigits(2);` and then `formatter.format(amount)`. That achieved what I needed but thank you for your other proposed solution. – Jaime Montoya Oct 28 '19 at 18:13
-
I do not know how this can be ACCEPTED answer, yet how it can have so many upvotes. The 2nd (BigDecimal) solution, has very serious bug. To explain it to the mortals: if you have 1.555 double, it is something like 1.55499999999999996461734734717435134543 as BigDecimal. After that "HALF UP" 2 places makes 1.555 look like 1.55. I have what to say for the other too. – H.A.H. Apr 20 '23 at 08:51
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));

- 202,709
- 46
- 318
- 350
-
6And with `DecimalFormat` you can also select the rounding mode; default will match the OP's example or they may want `RoundingMode.DOWN`. – Kevin Brock May 11 '10 at 07:03
-
1First two options give `-0.00` for a number greater than -0.005 and less than 0. This might not be optimal if you display the value on a report. – Voicu Nov 20 '14 at 23:01
-
@Voicu for your specific case, I think you should use 3 or more decimal places. That depends on how much is your error margin. – hmartinezd Sep 17 '15 at 17:13
-
3This answer is the *real* answer... the others round the double, which is an entirely different operation to formatting. – AStopher Mar 28 '16 at 18:46
-
what if you want to have the result in a double variable instead of a string? – Coder17 Oct 20 '17 at 10:38
-
-
not working in case of DecimalFormat df = new DecimalFormat("####0.00"); System.out.println(df.format(60.62499999999999)); – Bachas Aug 25 '21 at 10:45
-
@Bachas What do you mean by "not working"? It prints 60.62, which is the expected result. – Jesper Aug 25 '21 at 13:43
I think this is easier:
double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(time));
System.out.println(time); // 200.35
Note that this will actually do the rounding for you, not just formatting.
-
20Please note that this will break if the user locale is not US-en or similar. For example in Spanish, the format would be "#,##". Use Jonik's answer instead. – Jhovanny Nov 09 '14 at 21:11
-
-
@Jhovanny you cant declare a double like that double time = 200,3456 with throw errors... – Yunfei Chen Jul 10 '21 at 04:57
The easiest way, would be to do a trick like this;
double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;
if val starts at 200.3456 then it goes to 20034.56 then it gets rounded to 20035 then we divide it to get 200.34.
if you wanted to always round down we could always truncate by casting to an int:
double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;
This technique will work for most cases because for very large doubles (positive or negative) it may overflow. but if you know that your values will be in an appropriate range then this should work for you.
-
3Good simple answer. I would just add that `Math.Round` should be `Math.round`. And the result from `Math.Round(val);` should be a cast as a double as it normally returns a long: `val = (double) Math.round(val);` – dbjohn Dec 14 '10 at 15:51
-
1Perfect answer, because result of value will be calculated with **comma** in the other answers. For example, double value is **3.72** and if I use `format()` function, new double value changes **3,72** and If I wanna set this new value to double property, it will be throwed exception of _NumberFormatException: For input string: "3,72"_. But you got this logical operation, not function. Best regards. – RuudVanNistelrooy May 02 '14 at 05:54
-
1
Please use Apache commons math:
Precision.round(10.4567, 2)

- 3,815
- 8
- 35
- 63

- 3,847
- 2
- 23
- 27
-
1This doesn't actually do anything in a pass-by-value language like Java, let alone what the OP asked for. – user207421 Nov 17 '14 at 08:35
-
30@EJP why are you being so picky? all one has to do is assign the return value to a variable... – Hendy Irawan Dec 15 '14 at 12:08
-
4Note that internally, [Precision.round](http://commons.apache.org/proper/commons-math/javadocs/api-3.3/src-html/org/apache/commons/math3/util/Precision.html#line.395) simply converts the Double to a BigDecimal and back again, like in Jonik's solution. – sffc Dec 09 '16 at 21:13
-
3I think it is a very clean solution, even though it makes you dependent on a library. – Ivan Aranibar Feb 16 '17 at 15:10
-
@HendyIrawan It doesn't do what the OP asked for. It can't. No solution that stores the result in floating-point can possibly work. See my answer in the duplicate for why. – user207421 Mar 23 '19 at 22:31
function Double round2(Double val) {
return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
Note the toString()!!!!
This is because BigDecimal converts the exact binary form of the double!!!
These are the various suggested methods and their fail cases.
// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d
Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val)
// By default use half even, works if you change mode to half_up
Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;

- 9,474
- 36
- 90
- 105

- 716
- 5
- 6
-
8Should be the accepted answer because the accepted one is such messy compared to your clean and readable answer – singe3 Jul 01 '15 at 20:10
-
1I just changed ```BigDecimal(val.toString())``` by ```BigDecimal(Double.toString(value))``` to avoid error on val.toString() in case you use `double `instead `Double`. – Vifier Lockla May 09 '21 at 19:57
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value));

- 562
- 6
- 17

- 1,299
- 1
- 13
- 22
If you really want the same double, but rounded in the way you want you can use BigDecimal, for example
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();

- 779
- 7
- 8
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);

- 37,128
- 15
- 99
- 111

- 249
- 2
- 2
For two rounding digits. Very simple and you are basically updating the variable instead of just display purposes which DecimalFormat does.
x = Math.floor(x * 100) / 100;

- 5,721
- 9
- 48
- 78
Rounding a double is usually not what one wants. Instead, use String.format()
to represent it in the desired format.

- 776,304
- 153
- 1,341
- 1,358
-
3I need to round a double to use it as a granularity level in further calculations – odiszapc Mar 06 '16 at 05:56
-
@odiszapc: Then you're using the wrong datatype. You need to use arbitrary-precision types if you want to be able to specify arbitrary precision. – Ignacio Vazquez-Abrams Mar 06 '16 at 10:29
-
1I get doubles from DB, it's native DB type. But then I round it special to use rounded values as a key to build matrix. Of course this key is a formatted String gotten with String.format method. – odiszapc Mar 06 '16 at 15:02
In your question, it seems that you want to avoid rounding the numbers as well? I think .format() will round the numbers using half-up, afaik?
so if you want to round, 200.3456 should be 200.35 for a precision of 2. but in your case, if you just want the first 2 and then discard the rest?
You could multiply it by 100 and then cast to an int (or taking the floor of the number), before dividing by 100 again.
200.3456 * 100 = 20034.56;
(int) 20034.56 = 20034;
20034/100.0 = 200.34;
You might have issues with really really big numbers close to the boundary though. In which case converting to a string and substring'ing it would work just as easily.

- 496
- 5
- 11

- 244
- 1
- 7
-
1thanks for your answer. It is working fine if the value is 200.3456, but if the value is 200, then it should be 200.00 – Rajesh May 11 '10 at 07:08