-1

Is this not possible? Should the fraction be simplified to avoid 'non terminating decimal expansion' public class method {

BigDecimal a = new BigDecimal("1");
BigDecimal b = new BigDecimal ("22140");
BigDecimal c;


void cal () {
    
    System.out.println(c=a.divide(b));
    
}
Newbie
  • 11
  • 1
  • 1
    It is not possible. It can't be simplified. `BigDecimal` has no way to precisely represent a *non terminating decimal expansion*. And said expansion is a consequence of the maths. If you want a precise representation of that number, you need to use a different number system (i.e. class) that precisely represents all integer fractions. There isn't a standard class for this. – Stephen C Dec 06 '20 at 01:22
  • 4
    Besides `1/22140` is rational. – Stephen C Dec 06 '20 at 01:27
  • Thanks and yes I just checked, the (approx) value is 0.0000451671183378500451671183378500451671183378500451671183378500 – Newbie Dec 06 '20 at 02:26
  • Take your fraction and reduce it to lowest terms. If the denominator is not a power of 2, 5, or 10 then it cannot be represented exactly in decimal. – President James K. Polk Dec 06 '20 at 02:50
  • Maybe you find something here: [Best way to represent a fraction in Java?](https://stackoverflow.com/q/474535/12323248) – akuzminykh Dec 06 '20 at 03:00
  • Thanks everyone for your input, I've managed a walk around of the problem by rounding of the fraction, taking lower and upper bounds into account – Newbie Dec 07 '20 at 22:43

1 Answers1

4

I assume you are asking if it is possible to represent 1 / 22140 exactly as a BigDecimal. The answer to that is No. The BigDecimal class cannot represent values with a non-terminating decimal expansion, and there is no simplification of the equation that will allow it.

Q: Why?

A: Basically, mathematics. 1 / 22140 cannot be represented as m * 10s where m and s are finite integers.


There are two practical alternative approaches:

  1. You can use a MathContext argument when you do the division to specify how to round the number and how much precision to keep; e.g.

    c = a.divide(b, new MathContext(100, RoundingMode.HALF_UP));
    

    This will compute the result with 100 decimal digits of precision, rounding (in the conventional way) to the nearest representable value.

    Note that this approach gives you inexact results; e.g. (1 / 3) * 3 won't be exactly 1, no matter what you set the precision to in the MathContext.

  2. You can find and use a 3rd-party Rational or Fraction class, or write your own.

    Note that Java SE doesn't provide such a class.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216