牛顿迭代法求高精度开方

来源:互联网 发布:aix 安装软件 编辑:程序博客网 时间:2024/05/16 11:28


牛顿迭代法:http://baike.baidu.com/view/643093.htm

牛顿迭代公式:x(n+1)=x(n)-f(x(n))/f'(x(n))


如求2的平方根,构造函数 x^2 - 2 = 0;

dif为精度, 如果精度小于dif 跳出程序。这样可求出简单的平方根



[java] view plaincopy
  1. import java.math.BigDecimal;  
  2. import java.math.MathContext;  
  3. import java.math.RoundingMode;  
  4.   
  5. public class sqrt{  
  6.     public static void main(String[] args){  
  7.         //                  x^2 -2 = 0  
  8.         BigDecimal x1 = new BigDecimal(1);  
  9.         BigDecimal x2 = new BigDecimal(0);  
  10.         BigDecimal dif = new BigDecimal(0);  
  11.         BigDecimal precision = new BigDecimal(0.000000000000000000000000000000000000000000000000001);  
  12.         while(true){  
  13.             x2 = x1.subtract(x1.pow(2).subtract(new BigDecimal(2)).divide(x1.multiply(new BigDecimal(2)),100, BigDecimal.ROUND_HALF_EVEN));  
  14.               
  15.             if(x1.compareTo(x2)==1){  
  16.                 dif = x1.subtract(x2);  
  17.             }else{  
  18.                 dif = x2.subtract(x1);  
  19.             }  
  20.               
  21.             if(dif.compareTo(precision)==-1){  
  22.                 System.out.println(x1+","+x2);  
  23.                 break;  
  24.             }  
  25.               
  26.             x1 = x2;  
  27.         }  
  28.     }  
  29. }  


如果要求高精度,而 怎样确定dif小于小数点后100位?

使用java提供的大数类,后程序变为


[java] view plaincopy
  1. public class sqrt{  
  2.     public static void main(String[] args){  
  3.         //                  x^2 -2 = 0  
  4.         double x1=1,x2=0;  
  5.         double dif=0;  
  6.         while(true){  
  7.             x2 = x1 - (x1*x1-2)/(2*x1);  
  8.             if(x2>x1){  
  9.                 dif = x2-x1;  
  10.             }else{  
  11.                 dif = x1-x2;  
  12.             }  
  13.               
  14.             if(dif<0.000000000001){  
  15.                 System.out.println(x1+","+x2);  
  16.                 break;  
  17.             }  
  18.             x1 = x2;  
  19.         }  
  20.     }  
  21. }  

其中大数运算中出现除不尽的异常,后直接控制了位数,保留100位。

现在的问题是,如何确定精度dif是100,也就是怎样用Java表示出0.000……1 (小数点后100位)

考虑了很久,其实可以用  大数运算  用1除10的100次方。

改进代码如下:


[java] view plaincopy
  1. import java.math.BigDecimal;  
  2. import java.math.MathContext;  
  3. import java.math.RoundingMode;  
  4.   
  5. public class sqrt{  
  6.     public static void main(String[] args){  
  7.         //                  x^2 -2 = 0  
  8.         BigDecimal x1 = new BigDecimal(1);  
  9.         BigDecimal x2 = new BigDecimal(0);  
  10.         BigDecimal dif = new BigDecimal(0);  
  11.           
  12.         BigDecimal precision =x1.divide(new BigDecimal(10).pow(100));  
  13.         System.out.println(precision);  
  14.         while(true){  
  15.             x2 = x1.subtract(x1.pow(2).subtract(new BigDecimal(2)).divide(x1.multiply(new BigDecimal(2)),100, BigDecimal.ROUND_HALF_EVEN));  
  16.               
  17.             if(x1.compareTo(x2)==1){  
  18.                 dif = x1.subtract(x2);  
  19.             }else{  
  20.                 dif = x2.subtract(x1);  
  21.             }  
  22.               
  23.             if(dif.compareTo(precision)==-1){  
  24.                 System.out.println(x1+","+x2);  
  25.                 break;  
  26.             }  
  27.               
  28.             x1 = x2;  
  29.         }  
  30.     }  
  31. }  

0 0
原创粉丝点击