0

I have two BigDecimal in my java code, and I divide the first by the second.

Example :

Double price = new Double("18.2");
Double qte = new Double("2.6");

// Convert Integer number to double value
double res = price / qte;

System.out.println(res.intValue());

The result is : "6" (for double 6.99999) Why it is not just "7" ?!

I can make :

 System.out.println(new java.text.DecimalFormat("##").format(res));

To obtain 7, but it is the simplest/better solution ?

user2178964
  • 124
  • 6
  • 16
  • 40
  • 1
    You correctly create `BigDecimal` from strings instead of from `double`, but as soon as you use the `doubleValue()` to do actual calculation, all effects of `BigDecimal` are lost. In other words: your use of `BigDecimal` here has no effect. This is exactly the same as if you did simply `double res = 18.2 / 2.6;`. If you want to do *calculation* with `BigDecimal` you need to use its methods like `divide()`. – Joachim Sauer Aug 27 '21 at 12:56
  • Ok I updated the question, the problem is not on the Bigdecimal but it seems that double are not rounded by default, could you help me understand this ? Thx – user2178964 Aug 27 '21 at 13:04
  • Check the question linked at the top. The issue is more complicated than "not rounding". – Joachim Sauer Aug 27 '21 at 13:05
  • Besides: there's no reason to use `Double` here instead of `double`, so simply `double price = 18.2` (and similarly for `qte`) will reproduce the issue. – Joachim Sauer Aug 27 '21 at 13:07
  • Yeah I see, I understand a little bit better, but what is the best way to handle this in my code ? I can make a DecimalFormat("#") before display the result to have only the integer part, but it seems a complex solution... – user2178964 Aug 27 '21 at 13:07
  • Just try sth. like double result = new BigDecimal("18.2").divide(new BigDecimal("2.6")).doubleValue(); – Daniel Nuss Aug 27 '21 at 13:14
  • Thx, but the goal is to get only the integer part here – user2178964 Aug 27 '21 at 13:17
  • So way not use this instead?: int result = new BigDecimal("18.2").divide(new BigDecimal("2.6")).intValue(); – Daniel Nuss Aug 27 '21 at 13:18
  • That will truncate the fraction. Use `int result = new BigDecimal("18.2").divide(new BigDecimal("2.6")).setScale(0, RoundingMode.HALF_UP).intValue();` – Tenfour04 Aug 27 '21 at 13:19
  • @DanielNuss : it works great, so with BigDecimal it's ok, but with Double it's not ok. Very complex to understand all this for me... – user2178964 Aug 27 '21 at 13:21
  • @Tenfour04 : What is the advantage of this instead of DanielNuss answer ? Thx – user2178964 Aug 27 '21 at 13:27
  • Simplified explanation: doubles and floats have limited precision. There are theoretically infinite numbers between any two whole numbers. Some of that infinite precision is lost when the numbers are stored in binary in 64 bits. Do math with imprecise numbers and you get an imprecise result. Now 18.2 looks like you don't need much precision. After all, it only has 3 digits. But you're looking at it in base 10. In base 2 it would need infinite digits to represent exactly the same thing. – Tenfour04 Aug 27 '21 at 13:29
  • "new BigDecimal("1.999999").intValue()` will give you 1, not 2. It is dropping the fraction instead of rounding it the traditional way. – Tenfour04 Aug 27 '21 at 13:29
  • @Tenfour04 : In my case, I want to have the integer part, without rounding anything. So it's perfect to just take 1. About your explanation : So Double are "not precise" enough to represent a 3 digit number ? And BigDecimal are ? Crazy, I didn't notice this type of problem before today – user2178964 Aug 27 '21 at 13:34
  • There are certain numbers it can't represent perfectly, and some that it can. Roughly, it depends if you can represent it exactly in scientific notation in base 2 with only 64 bits. – Tenfour04 Aug 27 '21 at 13:37

0 Answers0