Reputation: 6954
I'm using commons-math 3.6.1.
I need to round a double value to 2 decimal
Let's assume this is my double value:
double d = 400.54540997260267;
Now by rounding this number I was expecting as result 400.54
Instead if my number was double d1 = 400.54640997260267;
I was expecting as result 400.55
Now I'm using this code:
Precision.round(d, 2, BigDecimal.ROUND_DOWN);
If I use as roundingMethod BigDecimal.ROUND_DOWN
I always get the lowest rounding. Which kind of rounding method should I use in order to get what I was expecting?
I tried the following code:
public class TestCalcoli
{
private static final Logger logger = LoggerFactory.getLogger(TestCalcoli.class.getName());
private void calc(double d)
{
double result = Precision.round(d, 2, BigDecimal.ROUND_HALF_DOWN);
double result2 = Precision.round(d, 2, BigDecimal.ROUND_HALF_UP);
logger.info("d--> "+d+" result --> "+result+" result2 --> "+result2);
}
@Test
public void calcola()
{
try
{
double d = 400.54540997260267;
double d1 = 400.54640997260267;
calc(d1);
calc(d);
}
catch (Exception e)
{
logger.error("errore", e);
}
}
}
CONSOLE OUTPUT:
2017-07-31 09:29:44,608 317 [main] INFO i.e.c.r.pwb.test.TestCalcoli - d--> 400.54640997260265 result --> 400.55 result2 --> 400.55
2017-07-31 09:29:44,612 321 [main] INFO i.e.c.r.pwb.test.TestCalcoli - d--> 400.54540997260267 result --> 400.55 result2 --> 400.55
Upvotes: 6
Views: 3559
Reputation: 10994
Here are the available rounding methods suitable for your problem and their respective output for the two values:
Method 400.54540997260267 400.54640997260267
--------------- ------------------ ------------------
ROUND_CEILING 400.55 400.55
ROUND_DOWN 400.54 400.54
ROUND_FLOOR 400.54 400.54
ROUND_HALF_DOWN 400.55 400.55
ROUND_HALF_EVEN 400.55 400.55
ROUND_HALF_UP 400.55 400.55
ROUND_UP 400.55 400.55
None of the methods provide the results you expect.
The reason for this is because the two neighbors of 400.54540997260267
and 400.54640997260267
are 400.54
and 400.55
. These neighbors are not equidistant from 400.54540997260267
or 400.54640997260267
. Therefore, the HALF rounding methods always round to the nearest neighbor which in both cases is 400.55
.
Borrowing from xenteros' answer, the desired results can be achieved using two rounding operations in succession. First round down with an extra digit of precision and then do the desired rounding with the desired precision:
double truncated = Precision.round(input, 3, BigDecimal.ROUND_FLOOR);
double rounded = Precision.round(truncated, 2, BigDecimal.ROUND_HALF_DOWN);
Upvotes: 4
Reputation: 15862
The easiest way to achieve what you want is to perform the following operations:
double d = 400.54540997260267;
Double temp = 1000*d;
temp = 1.0*temp.intValue()/1000;
Precision.round(temp, 2, BigDecimal.HALF_DOWN);
It removes digits from 4th decimal and then performs your desired rounding.
Upvotes: 1
Reputation: 1486
You should use HALF_UP if you want to round up for same distance, i.e. digit 5.
Upvotes: 6