-2

I need the following results:

10.17111 -> 10.17
10.17445 -> 10.18

I tried BigDecimal and DecimalFormat methods and RoundingMode class:

String value = "10.17111";
BigDecimal bd = new BigDecimal(value);
BigDecimal bdResult = bd.setScale(2, RoundingMode.UP);
String result = bdResult.toString();
System.out.println(result);

Print out = 10.18
Should be = 10.17

double ddd = 10.17111;
DecimalFormat d = new DecimalFormat("#.##");
d.setRoundingMode(RoundingMode.UP);
String outputResult = d.format(ddd).replace(',', '.');
System.out.println(outputResult);

Print out = 10.18
Should be = 10.17

And with BigDecimal:

String value2 = "10.17445";
Print out = 10.18
As I expected

And with DecimalFormat:

double ddd2 = 10.17445;
Print out = 10.17
Should be = 10.18

3 Answers3

1

If you really want to round digit-by-digit and you should really think long and hard about it (and perhaps tell us why if you are so inclined as I'm curious), then you can do any of the following, which I present as a thought exercise rather than as a recommendation that this is mathematically sound which I leave to you to decide for yourself:

1) Write an algorithm which checks from the digit you are rounding to and looks to see if it is a chain of 4's followed by a digit greater (10.44449) than 5 or just a number greater than 5 (10.49). If so round up to 11, otherwise use the normal rules.

2) Use RoundingMode.HALF_UP in a loop or recursively doing one digit at a time. If you have 10.17445, then you define a decimal format #.#### and round. Then #.### and round. Then #.## and round.

The reason there isn't a standard way to do this is because it is not standard.

John C
  • 500
  • 3
  • 8
  • Actually I take data from excel for my test automation and have to round it: https://www.screencast.com/t/BAt0rFWSY6Q – Armands Brūns Mar 17 '17 at 17:46
  • 1
    But why digit by digit? That is what Christopher and I are confused by. Why is 10.45 => 11 when it is closer to 10 then 11? – John C Mar 17 '17 at 17:47
  • I have to round all digits to value.xx Why you are confused? – Armands Brūns Mar 17 '17 at 17:54
  • I am confused because that's not the typical way to round numbers. The normal way is to have the cut off at the midpoint between two numbers. I.e. if I'm rounding to the units digit and my number is between 10 and 11. I do (10+11)/2 = 10.5. This is the midpoint. Anything less than that is closer to 10 so I round to 10. Anything greater than that is closer to 11 so I round to 11. Look at a meter stick. If I give you 49 cm, are you closer to 1 m or 0 m? – John C Mar 17 '17 at 17:57
  • Ok, what is the normal way (technical solution)? Because I don't have a big experience with rounding. – Armands Brūns Mar 17 '17 at 18:00
  • Agree with @JohnC. Armands, just check in excell how it would round this two numbers and make sure which rounding you really need. I provided my answer, cause I didn't even realize you needed something different. Good luck! – Rumid Mar 17 '17 at 18:03
  • RoundingMode.HALF_UP is the technical solution (unless you have very specific requirements). It will provide the behavior like I tried to demonstrate with the meter stick, it will round to whichever of the two possible values it is closer to. – John C Mar 17 '17 at 18:06
0

Just do all of the digits one by one, starting from the end, until you've done as many as you need to do.

public static BigDecimal RoundIt(BigDecimal valueToRound, int precision)
{
    BigDecimal result = valueToRound;

    for (int i = valueToRound.precision(); i >= precision; i--)
    {
        result = result.setScale(i, RoundingMode.HALF_UP);
    }

    return result;
}
D M
  • 1,410
  • 1
  • 8
  • 12
0

My workaround and it works fine:

public static String roundUp(String value) {

     BigDecimal bd = new BigDecimal(value.replace(',', '.'));
     BigDecimal bdResult = bd.setScale(4, RoundingMode.HALF_UP);
     BigDecimal bdResult2 = bdResult.setScale(3, RoundingMode.HALF_UP);
     BigDecimal bdResult3 = bdResult2.setScale(2, RoundingMode.HALF_UP);
     String result = bdResult3.toString();
     return result;

}