-1

Good evening:

I am having a problem rounding numbers with 3 or more decimals.

I have for example this number: 1544.565

And I am trying to round it to 1544.57


I have tried:

  • BigDecimal.ROUND_HALF_EVEN
  • BigDecimal.ROUND_UP
  • RoundingMode.HALF_EVEN
  • RoundingMode.HALF_UP
  • RoundingMode.CEILING
  • RoundingMode.UP

And all of them gave me the same wrong result: 1544.56 I am trying to obtain 1544.57

Any solutions please?

Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
DeathGun
  • 79
  • 2
  • 10
  • Possible duplicate of [round up to 2 decimal places in java?](https://stackoverflow.com/questions/11701399/round-up-to-2-decimal-places-in-java) – Michu93 Jul 09 '18 at 13:31
  • 1
    you should specify which is the rounding mode expected if you have 1544.564 otherwise more than one answer is possible but not all could be what you need – Aris2World Jul 09 '18 at 13:38
  • 1
    share the code please – azro Jul 09 '18 at 13:54
  • 1
    OP refuses to show a complete example, so I'll share my finding which is most likely the cause of the confusion here: if you take a float initialized with literal value 1544.565f, its real intern value will be like 1544.564999. Therefore, trying to round it to two decimal digits will be rounded to 1544.56. That is not so when doing the same with doubles. The problem therefore is thinking you're working with BigDecimals, when in truth you involved floating-point numbers in the calculations. – kumesana Jul 09 '18 at 14:24
  • @kumesana: You are probably right. I thought the same. But even a lot of doubles could be slighty under the *HALF*, so the only sure way is either to use strings to initialize the BigDecimals, or, if that is not possible, to use ROUND_UP. But that would also round x.564 up to x.57. – Rudy Velthuis Jul 09 '18 at 20:09
  • You should show your code. And try printing the number to console *before* you round it. Then you can see if it is **exactly** 1544.565, or slightly above or below (e.g. if you used a float or double to initiliaze it, instead of a string). Note that if you use HALF_EVEN, you always end up with an **even** final digit (as the name says) so you can never get .57. – Rudy Velthuis Jul 09 '18 at 20:20
  • Sure, my code is: System.out.println("ROUND_HALF_EVEN == " + number.setScale(2, BigDecimal.ROUND_HALF_EVEN).toString()); – DeathGun Jul 10 '18 at 06:07
  • 1
    *all* your code -_-° – kumesana Jul 10 '18 at 10:40
  • 1
    The code that is much more interesting is not shown yet: how you initialize the BigDecimal: with a string, with a float or with a double? Only in the first case, you will get *exact* numbers. Floats and doubles most of the time produce approximate values, that may not be **exactly halfway** between the higher digits. And again, HALF_EVEN will **always** produce an **even** last digit, so it can never be a 7. – Rudy Velthuis Jul 10 '18 at 12:21
  • Why don't you print out the number **before** you scale it. That should give you a great insight in *why* you don't get what you want. E.g. if it is initialized from a float, you get something like `1544.56494140625`, which is not exactly halfway between `1544.56` and `1544.57`. – Rudy Velthuis Jul 10 '18 at 12:32
  • @DeathGun Please accept the answer which helped you most in solving your problem. It helps future readers. If the answers weren't helpful leave comments below them. So the poster can update them accordingly. – Roshana Pitigala Jul 29 '18 at 17:59

3 Answers3

3

Try ROUND_UP with scale 2:

BigDecimal bigDecimal = new BigDecimal("1544.565");
System.out.println(bigDecimal.setScale(2, BigDecimal.ROUND_UP)); // 1544.57
xingbin
  • 27,410
  • 9
  • 53
  • 103
0

In JDK 1.8 you can use java.text.DecimalFormat for this

new DecimalFormat("0.00").format(1544.565)

OUTPUT

1544.57

Read the doc to identify more pattern characters.


UPDATE 2 (answering this comment):

You are using BigDecimal.ROUND_HALF_EVEN use BigDecimal.ROUND_HALF_UP instead.

Don't use BigDecimal.ROUND_UP, it always rounds up the number.

BigDecimal.ROUND_HALF_UP

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
~Java doc~

Example:

BigDecimal number = new BigDecimal("1544.565");
System.out.println(number.setScale(2, BigDecimal.ROUND_HALF_UP).toString());

Output

1544.57

Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
  • 1
    This example is not great because it's hard to figure out whether it should be rounded up or down without making a couple of tests. A BigDecimal would have been better. – kumesana Jul 09 '18 at 13:52
  • @DeathGun what is your java version? – Roshana Pitigala Jul 09 '18 at 13:53
  • @DeathGun Sorry it gives 1544.56 in JDK 1.7. Wait I'll give you a better solution – Roshana Pitigala Jul 09 '18 at 14:00
  • It is weirder than weird that changing the SDK version would give different results with this -_-°. I didn't keep around a JDK 1.7 to verify, unfortunately. – kumesana Jul 09 '18 at 14:05
  • Yes, it is weird that with different JDK they give us different results. I am trying to do it yet. – DeathGun Jul 09 '18 at 14:26
  • @DeathGun it's not weird. they are called improvements. as the version number upgrades you tend to see more and more improvements. the real question would be why do you use a older JDK version? – Roshana Pitigala Jul 09 '18 at 14:27
  • @RoshanaPitigala there was no improvement in that area. Floating-point numbers stayed the same, as did DecimalFormat's specifications. At best a specific bug that would exist with some numbers has been fixed, but this is unlikely to be the case. – kumesana Jul 09 '18 at 14:30
  • My code is: System.out.println("ROUND_HALF_EVEN == " + number.setScale(2, BigDecimal.ROUND_HALF_EVEN).toString()); – DeathGun Jul 10 '18 at 06:09
  • I tried ROUND_HALF_UP too and it continue giving me the result incorrect. – DeathGun Jul 13 '18 at 08:36
  • @DeathGun No. I tested it with JDK 1.7 works fine for me. – Roshana Pitigala Jul 13 '18 at 13:21
0

Confirmed here;

double a = 1544.565;
double rounded = Math.round(a * 100.0) / 100.0;
System.out.println(rounded);

Outputs 1544.57.

Nick
  • 823
  • 2
  • 10
  • 22