12

In java am trying to find an efficient way to round a BigDecimal to two decimals, Up or Down based on a condition.

 IF condition true then:
    12.390 ---> 12.39
    12.391 ---> 12.40
    12.395 ---> 12.40
    12.399 ---> 12.40

 If condition false then:
    12.390 ---> 12.39
    12.391 ---> 12.39
    12.395 ---> 12.39
    12.399 ---> 12.39

What is the most efficient way to accomplish this?

richs
  • 4,621
  • 10
  • 42
  • 55
  • Are you just going to convert it into a string or display it, or are you going to use it in some other way? – Robin Green Apr 15 '11 at 20:17
  • It is being passed to a third party library method that takes a BigDecimal. The library will then take the value and add it to a string message. – richs Apr 15 '11 at 20:20

3 Answers3

30
public static BigDecimal round(BigDecimal d, int scale, boolean roundUp) {
  int mode = (roundUp) ? BigDecimal.ROUND_UP : BigDecimal.ROUND_DOWN;
  return d.setScale(scale, mode);
}
round(new BigDecimal("12.390"), 2, true); // => 12.39
round(new BigDecimal("12.391"), 2, true); // => 12.40
round(new BigDecimal("12.391"), 2, false); // => 12.39
round(new BigDecimal("12.399"), 2, false); // => 12.39
maerics
  • 143,080
  • 41
  • 260
  • 285
  • 8
    The mode should be RoundingMode.FLOOR and RoundingMode.CEILING instead of BigDecimal.ROUND_UP and BigDecimal.ROUND_DOWN. – Mr. Nobody Apr 18 '11 at 14:52
1
num = num.setScale(condition ? RoundingMode.UP : RoundingMode.DOWN);

But note that your spec is not entirely clear when it comes to negative numbers. Take a look at the various rounding modes in the API doc and see what exactly you need.

Michael Borgwardt
  • 335,521
  • 76
  • 467
  • 706
1

I suggest the following (standing on the shoulders of giants...):

public BigDecimal roundNumber(final BigDecimal number, final boolean isFloor){
     return number.setScale(2, isFloor ? RoundingMode.FLOOR 
                                       : RoundingMode.CEILING);
}
Mr. Nobody
  • 377
  • 1
  • 14