Timeline for How to round a number to n decimal places in Java
Current License: CC BY-SA 3.0
23 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Jan 27, 2023 at 15:54 | comment | added | Sergey Zolotarev | It returns a number with zeroes at the end | |
| May 6, 2022 at 7:25 | comment | added | SmAxlL | this method is faster, but it doesn't work if (the value * 10000d) > Long.MAX as Math.round() will return the closes long which is Long.MAX. put in another way, Math.pow(10, x) must be <= Long.MAX | |
| Oct 25, 2019 at 15:55 | comment | added | fishinear | This method method will never work reliably. The reason is that the result is a not a string but a double value, which has a binary representation internally. But the result will likely not be representable as a binary number. | |
| Jun 21, 2017 at 4:47 | comment | added | maaartinus |
@ToolmakerSteve When the initial number has three decimals and you want only two, this gives you the right (HALF_EVEN rounded) answer: x = Math.rint(1000*x); x = Math.rint(x/10.0); return x / 100.0;. Obviously, the result is not exactly 365.34, but it's the closest approximation and it prints out like this.
|
|
| Sep 8, 2016 at 6:16 | comment | added | shmosel |
I don't think the (double) cast is necessary.
|
|
| Sep 16, 2015 at 12:17 | history | edited | Michael | CC BY-SA 3.0 |
added 2 characters in body
|
| Aug 28, 2015 at 3:17 | comment | added | ToolmakerSteve |
@SebastiaanvandenBroek: Wow I never knew it was that easy to get a wrong answer. However, if one is working with non-exact numbers, one must recognize that any value is not exact. 265.335 really means 265.335 += tolerance, where tolerance depends on previous operations and range of input values. We do not know the true, exact value. At the edge values, either answer is arguably correct. If we need to be exact, we shouldn't work in double. The fail here isn't in converting back to double. Its in OP thinking he can rely on the incoming 265.335 as being exactly that.
|
|
| Jul 15, 2015 at 7:38 | comment | added | gen.error |
@AndiJay: "If you get paid by the clock cycle, this is what you should be doing" -- I disagree. If I was paid by clock cycle, I would use the DecimalFormat to make my code as slow as possible: the more clock cycles it requires, the more money for me ;)
|
|
| Dec 7, 2014 at 10:47 | review | Suggested edits | |||
| Dec 7, 2014 at 11:09 | |||||
| Jul 13, 2014 at 8:04 | comment | added | hamish | sure you lose some tincy wincy precision on the ROUND_EVEN/ROUND_UP on those fringy cases, but who cares.. its super duper fast! that is why programmers use double in the first place. you are rounding those extras off the end anyway so they are obviously not significant to you or your users. otherwise you would not be using double (aka floating point) in the first place. | |
| Jul 13, 2014 at 7:56 | comment | added | hamish | 1.005 == 1.00 and 265.335 == 265.33 -> so what! it is fine. there is conversions of floating point going into round, there is conversions of floating point going into the division, there is floating point conversions going into 100.0 you just have to accept that floating point is FLOATING POINT... it is approximation! of decimals. floating point double is fast!!! sure you lose some precision, but who cares.. its super duper fast! | |
| May 19, 2014 at 14:23 | comment | added | Matthias Braun |
This fails with very small values too: (double)Math.round(1.005 * 100) / 100 == 1.0 Don't use it!
|
|
| Apr 10, 2014 at 17:21 | comment | added | satur9nine | @ChrisCudmore has the best answer here scroll down now, also Math.pow(10,20) is way too big, if you need 20 decimal places of precision then double is not for you. | |
| Nov 14, 2013 at 13:51 | comment | added | Sebastiaan van den Broek | Be very careful when using this method (or any rounding of floating points). It fails for something as simple as 265.335. The intermediate result of 265.335 * 100 (precision of 2 digits) is 26533.499999999996. This means it gets rounded down to 265.33. There simply are inherent problems when converting from floating point numbers to real decimal numbers. See EJP's answer here at stackoverflow.com/a/12684082/144578 | |
| Aug 19, 2013 at 14:18 | comment | added | sambe | @RobertTupelo-Schneck This does not work, because double only has a precision of approximately 14 decimal places (anything more than that will not be accurate anyway) | |
| Jan 15, 2013 at 15:19 | comment | added | Alvin Wong |
I think doing multiplication will be faster than division, so (double)Math.round(value * 100000) * 0.000001
|
|
| Oct 3, 2012 at 18:51 | comment | added | Robert Tupelo-Schneck |
Indeed, this fails: Math.round(0.1 * Math.pow(10,20))/Math.pow(10,20) == 0.09223372036854775.
|
|
| Oct 2, 2012 at 3:12 | comment | added | user207421 | This technique fails in over 90% of cases. -1. | |
| Aug 25, 2012 at 12:33 | comment | added | arkon | @Andi Jay I'm not saying you're wrong or right, but you can't really say that an isolated test on a single machine confirms your theory. | |
| Jul 10, 2012 at 14:35 | comment | added | jsrz | UPDATE: I just confirmed that doing this IS WAY faster than using DecimalFormat. I looped using DecimalFormat 200 times, and this method. DecimalFormat took 14ms to complete the 200 loops, this method took less than 1ms. As I suspected, this is faster. If you get paid by the clock cycle, this is what you should be doing. I'm surprised Chris Cudmore would even say what he said to be honest. allocating objects is always more expensive than casting primitives and using static methods (Math.round() as opposed to decimalFormat.format()). | |
| Jul 9, 2012 at 20:01 | comment | added | jsrz | I think this is better than using DecimalFormat though. DecimalFormat will allocate various objects implicitly, and also a String on each call to decimalFormat.Format(). I would image it's better to cast to a few primatives than allocate objects. | |
| Sep 30, 2008 at 16:22 | comment | added | Chris Cudmore | Math.round uses an internal cast to long, which you are then casting back to double. | |
| Sep 30, 2008 at 16:07 | history | answered | asterite | CC BY-SA 2.5 |