0

I have two double values

double a = 1.07522;
double b = 1.0752;

and rounding multiplier value

public static final double ROUND_MULTIPLIER = 100000.0;

So there always should be 5 decimal places.

I need to subtract two double values and get result as a - b = 0.00002.

How can I do this with using ROUND_MULTIPLIER ?

I tried using BigDecimal as

BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b)).round(new MathContext((int)ROUND_MULTIPLIER)); 

but it not always works, sometimes return 2E-16, it returns weird value when try add to second value as below

BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b + 0.00002)).round(new MathContext((int)ROUND_MULTIPLIER));

I need to use ROUND_MULTIPLIER.

ACz
  • 567
  • 5
  • 22

4 Answers4

1

I don't understand why you must use ROUND_MULTIPLYER and what the exact reason of it's existance is, so I can only guess.

Forcing the code to use ROUND_MULTIPLYER:

public static final double ROUND_MULTIPLIER = 100000.0;

public void foobar()
{
    double a = 1.07522;
    double b = 1.0752;

    BigDecimal opA = BigDecimal.valueOf(a);
    BigDecimal opB = BigDecimal.valueOf(b);

    BigDecimal result = opA.subtract(opB);

    result = result.multiply(BigDecimal.valueOf(ROUND_MULTIPLIER));

    int cutResult = result.intValue();

    result = BigDecimal.valueOf(cutResult / ROUND_MULTIPLIER);

    System.out.println(result);
}

The output of this is

 0.000020

Is that what you want? The code is definitly object to optimization, but I let that up to you to do ;-)

Korashen
  • 2,144
  • 2
  • 18
  • 28
  • It works but now is impossible to get double from the `result`. When I try `result.doubleValue()` it return 2.0E-5 – ACz Jan 25 '17 at 13:42
  • 1
    The primitive double will be converted to a String via `Double.toString(double)`. That will render the output in the scientific notation. Check this question for an answer: http://stackoverflow.com/questions/16098046/how-to-print-double-value-without-scientific-notation-using-java – Korashen Jan 25 '17 at 13:45
  • Tried Double.toString(result) but it returned the same 2.0E-5 – ACz Jan 25 '17 at 13:50
  • `System.out.println(result)` and `System.out.println(Double.toString(result))` are the exact same things. Check the linked question, it has a solution to formatting a double correct. – Korashen Jan 25 '17 at 13:55
0

Use bigDEcimal and set the scale giving the number of decimals you need

    final BigDecimal a = new BigDecimal(1.07522);
    final BigDecimal b = new BigDecimal(1.0752);
    final BigDecimal result = a.subtract(b);
    int newScale = 10; //10 decimals
    System.out.println(result.setScale(newScale, BigDecimal.ROUND_UP));
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
0
 BigDecimal decimal = new BigDecimal(1.07522);
 BigDecimal decimal1 = new BigDecimal(1.0752);
 System.out.println(decimal.subtract(decimal1).setScale(5, RoundingMode.DOWN));
shreyansh jogi
  • 2,082
  • 12
  • 20
  • It works but I need to use the ROUND_MULTIPLIER, I cant hardcode the scaling value as 5. – ACz Jan 25 '17 at 12:45
  • @ACz You could either save the "5" instead of the 10000 in a constant or you can calculate the 5 using the logarithm. – J Fabian Meier Jan 25 '17 at 13:29
0

BigDecimal is the way to go, but why is the ROUND_MULTIPLIER a double value if you cast it to int anyways. Maybe that is where you get your rounding issues from? Give it a spin with an int-multiplier :)

Edit: using setScale() setting a proper rounding mode is usually a better choice, but you insist on using the multiplier, right?

Nikolas
  • 2,066
  • 1
  • 19
  • 20
  • Yes, I need to use this ROUND_MULTIPLIER and I cast it to Int because MethContext need int. – ACz Jan 25 '17 at 12:45