BigDecimal 类中的 Java 运行时错误“非终止十进制扩展;没有精确的可表示的十进制结果”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4678985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java run-time error " Non-terminating decimal expansion; no exact representable decimal result" in BigDecimal class
提问by Nayef
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.
选择“正不正确积分”或“负不正确积分”时,它给我一个错误,错误是线程“main”中的异常java.lang.ArithmeticException:非终止十进制扩展;没有精确的可表示的十进制结果。
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"))));
}
}
回答by kgiannakakis
回答by Haozhun
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.
当您对 BigDecimal 执行 1/3 并且没有指定结果应该有多精确以及舍入方法应该是什么样的时,就会发生这种情况。
请参阅 javadoc ( http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html)
您可以使用 MathContext 对象将 precision 和 roundupMethod 包装在一起。您也可以选择直接指定它。将该信息添加到构造函数或调用divide时都可以。
回答by mdrg
Divide method throws this exception if the resulting number have infinite decimal expansion. In this case, you need to provide a MathContext, which will define how the number will be rounded, so that it have a finite value.
如果结果数字具有无限十进制扩展,则 Divide 方法将引发此异常。在这种情况下,您需要提供一个 MathContext,它将定义如何舍入数字,使其具有有限值。