0

Basically I wrote a method for reciprocal value of a BigDecimal instance:

public class Main{

public static void main(String[] args) {

    BigDecimal value1 = new BigDecimal("88");
    BigDecimal reciproc1 = reciproc(value1);
    BigDecimal reciproc2 = reciproc(reciproc1);
    System.out.println("Initial value: " + value1);
    System.out.println("Reciproc1: " + reciproc1);
    System.out.println("Reciproc2: " + reciproc2);
}

public static BigDecimal reciproc(BigDecimal value) throws ArithmeticException{
    if (value.equals(new BigDecimal("0"))){
        throw new ArithmeticException("Cannot divide by zero");
    }
    return new BigDecimal("1").divide(value, 20, RoundingMode.HALF_UP);
}

}

The output will be like:

Initial value: 88
Reciproc1: 0.01136363636363636364
Reciproc2: 87.99999999999999997185

It's obvious that variable reciproc2 must be equal to an initial value. Unfortunately, it's not the case with my method. I've tried to resolve this by manipulating with scale and rounding mode but all my attempts were futile:

return new BigDecimal("1").divide(value, 3, RoundingMode.HALF_UP);
Reciproc2: 90.909

or

return new BigDecimal("1").divide(value, 15, RoundingMode.CEILING);
Reciproc2: 87.9999999999999999999995073
void
  • 731
  • 2
  • 11
  • 26
  • You can't expect a 100% mathematic precision if you're rounding. In addition, 1/88 is a periodic number, which will make it impossible to get the same value in two inverse operations. Nevertheless, you could spice up some tricks to get your result, like, saving the number of decimals the original number has and truncate/round to that extent of decimals the output. Hope that helps. – Keews Jul 22 '15 at 08:12
  • Yeah I would agree, the only way you're going to get it to work is fudging the value after the operation. Though as what you've written is fairly pointless here I'm assuming this is part of a larger problem where you do no have the original value to hand to allow fudging. Also don't do value.equals(new BigDecimal("0")) instead do (new BigDecimal("0")).equals(value) – Andrew Aitken Jul 22 '15 at 08:25
  • If you want to print value the same as your initial value, you just round your `reciproc2` when you print it. Additionally you should use `compareTo` instead of `equals` for checking zero divisor. For `BigDecimal`, `0` doesn't equal `0.00` – cshu Jul 22 '15 at 09:12

1 Answers1

0

Probably not the solution you are looking for, but it could be convenient to use Apache commons-lang Fraction:

public static void main(String[] args) {
    Fraction value1 = Fraction.getFraction(88, 1);
    Fraction reciproc1 = reciproc(value1);
    Fraction reciproc2 = reciproc(reciproc1);
    System.out.println("Initial value: " + value1.toProperString() + " " + value1.doubleValue());
    System.out.println("Reciproc1: " + reciproc1.toProperString() + " " + reciproc1.doubleValue());
    System.out.println("Reciproc2: " + reciproc2.toProperString() + " " + reciproc2.doubleValue());
}

public static Fraction reciproc(Fraction value) throws ArithmeticException{
    if (value.equals(Fraction.ZERO)){
        throw new ArithmeticException("Cannot divide by zero");
    }
    return Fraction.ONE.divideBy(value);
}

Which outputs:

Initial value: 88 88.0
Reciproc1: 1/88 0.011363636363636364
Reciproc2: 88 88.0
jdmuriel
  • 118
  • 1
  • 5