Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java run-time error " Non-terminating decimal expansion; no exact representable decimal result" in BigDecimal class

it give me an error when choosing "Positive improper integration"or"Negative improper integration" the error is Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

 at java.math.BigDecimal.divide(BigDecimal.java:1603)
 at SE_Project_2.calculate(SE_Project_2.java:55)
 at SE_Project_2.main(SE_Project_2.java:45)

Code:

 import java.math.BigDecimal;
 import javax.swing.JOptionPane;

 public class SE_Project_2 {

  private static BigDecimal C0 =   new BigDecimal("0.1713245");
  private static BigDecimal C1 =   new BigDecimal("0.3607616");
  private static BigDecimal C2 =   new BigDecimal("0.4679139");
  private static BigDecimal C3 =   new BigDecimal("0.4679139");
  private static BigDecimal C4 =   new BigDecimal("0.3607616");
  private static BigDecimal C5 =   new BigDecimal("0.1713245");
  private static BigDecimal X0 =   new BigDecimal("-0.932469514");
  private static BigDecimal X1 =   new BigDecimal("-0.661209386");
  private static BigDecimal X2 =   new BigDecimal("-0.238619186");
  private static BigDecimal X3 =   new BigDecimal("0.238619186");
  private static BigDecimal X4 =   new BigDecimal("0.661209386");
  private static BigDecimal X5 =   new BigDecimal("0.932469514");
  private static BigDecimal a=new BigDecimal("0"),b=new BigDecimal("0");
  private static int y;
     public static void main(String[] args) {
         Scanner in = new Scanner(System.in);
         try{
          String[] o = {"Positive improper integration","Negative improper integration","Normal integration"};
          y = JOptionPane.showOptionDialog(null,"Welcome to my program! \nYahya Al-Buluwi\nIt can work for big decimal numbers.\n\nThis program will find the integral of: \nf(x)= 5x + 3 dx\nBy using the 6-points Gauss Legendre Quadrature formulae.\n\n What choise is prefered to you?","Welcome",JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,null,o,o[2]);
    BigDecimal sum = null;


if (y==2){
 a = new BigDecimal((String)JOptionPane.showInputDialog(null,"Enter the value of a:","Enter the value of a", JOptionPane.QUESTION_MESSAGE));
       b = new BigDecimal((String)JOptionPane.showInputDialog(null,"Enter the value of b:","Enter the value of b", JOptionPane.QUESTION_MESSAGE));
}
sum = calculate(X0,C0).add(calculate(X1,C1).add(calculate(X2,C2)).add(calculate(X3,C3).add(calculate(X4,C4).add(calculate(X5,C5)))));
System.out.println("y=" + y);
JOptionPane.showMessageDialog(null,"The 6-points Gauss Legendre Quadrature formulae solution according to \na= " + a+"\nb= "+b+" \nis:   "+ sum,"Result",JOptionPane.INFORMATION_MESSAGE);

     }catch(Exception e){
      JOptionPane.showMessageDialog(null,"Ooops! an error has occured! the program will be terminated.","Error",JOptionPane.ERROR_MESSAGE);
      calculate(X0,C0).add(calculate(X1,C1).add(calculate(X2,C2)).add(calculate(X3,C3).add(calculate(X4,C4).add(calculate(X5,C5)))));
System.out.println("y=" + y);
JOptionPane.showMessageDialog(null,"The 6-points Gauss Legendre Quadrature formulae solution according to \na= " + a+"\nb= "+b+" \nis:   "+  calculate(X0,C0).add(calculate(X1,C1).add(calculate(X2,C2)).add(calculate(X3,C3).add(calculate(X4,C4).add(calculate(X5,C5))))),"Result",JOptionPane.INFORMATION_MESSAGE);

     }
 }
public static BigDecimal calculate(BigDecimal x, BigDecimal c){
  BigDecimal h = x.multiply(new BigDecimal("0.5"));
  if(y==0){
   //     PI= (1/(.5x)**2)*((5/(.5+.5x))+3)
   return (((new BigDecimal("1")).divide(h.pow(2))).multiply((new BigDecimal("3")).add((new BigDecimal("5")).divide((new BigDecimal("0.5")).add(h)))));
  }
  if(y==1){
   //        NI= (1/(-.5x)**2)*((5/(-.5-.5x))+3)
   return ((new BigDecimal("1").divide((h.negate()).pow(2))).multiply(new BigDecimal("3").add(new BigDecimal("5").divide(new BigDecimal("-0.5").add(h.negate())))));
  }

 BigDecimal sum = (b.add(a)).divide(new BigDecimal("2"));
    BigDecimal diff =(b.add(a.negate())).divide(new BigDecimal("2"));
    return c.multiply(diff.multiply((((diff.multiply(x)).add(sum)).multiply(new BigDecimal("5"))).add(new BigDecimal("3"))));

}
}
like image 368
Nayef Avatar asked Jan 13 '11 10:01

Nayef


2 Answers

This happens when you do 1/3 on BigDecimal and don't specify how precise the result should be and what the round method should be like.
See javadoc (http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html)
You may use a MathContext object to wrap up precision and roundupMethod together. You may also choose to specify it directly. Add that information to constructor or when calling divide are both ok.

like image 43
Haozhun Avatar answered Nov 14 '22 23:11

Haozhun


You probably need to use one of the divide methods that specify the rounding mode.

Read also here.

like image 153
kgiannakakis Avatar answered Nov 15 '22 00:11

kgiannakakis