0

Here it is what we have tried but none of those things work...

BigDecimal Total_Discount=new BigDecimal(10.00); 
BigDecimal Amount_To_User=new BigDecimal(00.00); 
BigDecimal Amount_To_Me=new BigDecimal(00.00);          

Amount_To_User=Total_Discount.multiply(new BigDecimal(0.65)).setScale(2,BigDecimal.ROUND_UP); //65% of the amount
Amount_To_Me=Total_Discount.multiply(new BigDecimal(0.35)).setScale(2,BigDecimal.ROUND_UP); //35% of the amount

Dividing the values by % 65 and 35 so 10 will be 6.50 and 3.50 but i am getting 6.51 by using BigDecimal.DOWN i am getting 6.50 i have already values with 6.51 which i need to change to 6.50

Amount_To_User=Amount_To_User.setScale(2, BigDecimal.ROUND_CEILING);
System.out.println(Amount_To_User); //Gives the value 6.51

I want to change that 6.51 to 6.50 but this doesn't work

f-CJ
  • 4,235
  • 2
  • 30
  • 28
Gopi Lal
  • 417
  • 5
  • 23
  • 1
    If you want to split the amount you should better only calculate one value by multiplication and the other by subtraction from your total account. In this case the formula `total = am_user + am_me` is satisfied. – Robert Apr 29 '16 at 11:03
  • DO NOT USE FLOATING POINT VALUES as values for Bigdecimals. Use integers or strings and e.g. `valueOf(int)` or `new BigDecimal(string)`. Stay away from floating point if you want the accuracy BigDecimals provide. – Rudy Velthuis May 02 '16 at 00:37

1 Answers1

4

TL;DR: Use BigDecimal.ROUND_HALF_UP as rounding Mode and/or use Strings as Input instead of double to create a BigDecimal.

Explenation

Compare the Documentation. Here is what you want:

BigDecimal.ROUND_HALF_UP

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up. Behaves as for ROUND_UP if the discarded fraction is ≥ 0.5; otherwise, behaves as for ROUND_DOWN. Note that this is the rounding mode that most of us were taught in grade school.

VS. what you have used.

BigDecimal.ROUND_CEILING (in your case behaves like BigDecimal.ROUND_UP, see below)

Rounding mode to round towards positive infinity. If the BigDecimal is positive, behaves as for ROUND_UP; if negative, behaves as for ROUND_DOWN. Note that this rounding mode never decreases the calculated value.

You allways round up. and you have a number with decimal places to round because you use a double as Input to create your BigDecimal (see below for an example).

BigDecimal.ROUND_UP

Rounding mode to round away from zero. Always increments the digit prior to a nonzero discarded fraction. Note that this rounding mode never decreases the magnitude of the calculated value.

In Addition you should create your BigDecimals from String input not from double. Use quotes " on the value in the Constructor.

BigDecimal total_Discount = new BigDecimal("10.00");
BigDecimal amount_To_User = new BigDecimal("00.00");
BigDecimal amount_To_Me = new BigDecimal("00.00");

amount_To_User = total_Discount.multiply(new BigDecimal("0.65")).setScale(2, BigDecimal.ROUND_HALF_UP);
amount_To_Me = total_Discount.multiply(new BigDecimal("0.35")).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(amount_To_User); //6.50
System.out.println(amount_To_Me); //3.50

This will show you why:

System.out.println(new BigDecimal(0.65));
//prints 0.65000000000000002220446049250313080847263336181640625
System.out.println(new BigDecimal("0.65"));
//prints 0.65

A Double has not a perfect precision on every decimal digit while a String has it.

Simulant
  • 19,190
  • 8
  • 63
  • 98
  • This is an interesting comment about Strings and Doubles. I'm curious if there is a performance factor as well? The string just gives you digits, while the Double seems to actually perform some sort of operation to convert a Double to a BigDecimal, which seems as if a String would be faster... I wonder if this is the case for a lot of things. – XaolingBao Apr 30 '16 at 00:21