Home » Java » Commons-math rounding double

# Commons-math rounding double

Questions:

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
``````

You should use HALF_UP if you want to round up for same distance, i.e. digit 5.

###

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);
``````

###

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.