-2

I'm facing a new problem..I use BigDecimal for money input. There is a little problem. Let's take a look at this piece of code:

BigDecimal a = BigDecimal.valueOf(5);
BigDecimal b = BigDecimal.valueOf(3);
BigDecimal result = a.divide(b);

The result is:

1.67

But if I do:

1.67 * 3 = 5.01

And that's cause problem in my code. So I need to obtain exactly 5. So 5/3 should be 1.67 + 1.67 + 1.66. Is it possible to achieve that?

Nicola
  • 301
  • 3
  • 20
  • 3
    This statement: `"The result is: 1.67"` is inherently *wrong*. The String representation may be `1.67`, but that is certainly not the true numeric result held by the `result` field. Your question is in fact an [xy problem](http://xyproblem.info) question. – Hovercraft Full Of Eels Dec 15 '18 at 23:18
  • 4
    Question - please write out `5/3` as a decimal. On pen and paper. – Boris the Spider Dec 15 '18 at 23:19
  • *So 5/3 should be 1.67 + 1.67 + 1.66. Is it possible to achieve that?* No. – Elliott Frisch Dec 15 '18 at 23:20
  • 1
    "_5/3 should be 1.67 + 1.67 + 1.66_" - in what number system? Division divides equally in every common number system. – Boris the Spider Dec 15 '18 at 23:21
  • @BoristheSpider yes, I know that 5/3 is 1,666666667...I mean..if I need to divide 5€ for 3 person, what's the correct system to achieve that? – Nicola Dec 15 '18 at 23:22
  • @Nicola rounding. Round down to 2dp (cents). Then give one person the difference. Obviously this only works for a small enough number of people... – Boris the Spider Dec 15 '18 at 23:22
  • @BoristheSpider, can you tell me the function, please? Or give me an example for my code? – Nicola Dec 15 '18 at 23:23
  • 4
    If you literally have 5 euros and you want to divide it among three people, somehow you need to decide who gets one cent more and who gets one cent less. There is no inherent way to do this: it takes an explicit decision. In code, that explicit decision needs to be made by explicit code. – Daniel Pryden Dec 15 '18 at 23:24
  • @DanielPryden yes, that's exactly what I mean. How can I decide in the code the person who gets one cent more and who gets one cent less? – Nicola Dec 15 '18 at 23:25
  • @Nicola that's just it, there is no "algorithm" to decide this. You yourself have to find out what is most fair. If this were my code, the 1 cent would go to my private account. – Hovercraft Full Of Eels Dec 15 '18 at 23:27
  • @HovercraftFullOfEels ok guys,I think I understand the problem and how to resolve it. Thank you all for the quick answers! – Nicola Dec 15 '18 at 23:28
  • 1
    @HovercraftFullOfEels https://en.m.wikipedia.org/wiki/Office_Space? – Boris the Spider Dec 15 '18 at 23:32
  • 2
    @Nicola In a real business app you would ask your financial executives, accountants, or bookkeepers for their policy on where to allocate the extra penny. When I’ve built invoicing or purchase order or accrual systems, I’ve usually added the extra penny (or any extra fractional amount needed to balance a number) to the last item I happen to be looping in my code. But in some cases another policy might make sense such as the largest value item getting the extra amount. – Basil Bourque Dec 16 '18 at 01:42

1 Answers1

3

If you execute that code snippet you will get the following exception, as shown in live code at IdeOne.com.

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result

Take a look at this other thread:

ArithmeticException thrown during BigDecimal.divide

You can tell BigDecimal how to handle recurring decimals.

If you instead execute something like this:

    BigDecimal a = BigDecimal.valueOf(500, 2);
    BigDecimal b = BigDecimal.valueOf(300, 2);
    BigDecimal result = a.divide(b, BigDecimal.ROUND_HALF_UP);
    System.out.println(result);

Then you would indeed have a result of 1.67

As to the question of how to achieve the 1.67 + 1.67 + 1.66 AFAIK you're gonna need to handle that yourself.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154