下面的程序做了很久了,可能是double的问题,计算的时候总是有误差,请高手指点。
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;class Newton1 {

public static Newton1 f = new Newton1();
public static void main (String[] args){

for(double v= 1; v < 10; v = v + 1){

for (int m = 100; m <= 1000; m = m + 100){
f.newton(m,p/10);
}
} }
public  void newton (int x,double y){
int n, max,y1;
double x1, c1, eps;
max = 50; 
eps = 1.0e-5; 
x1 = 0;
f.setM(x);
f.setP(y);
for (y1 = 1; y1 < f.getM(); y1++) {                          System.out.println( y1 );
                          x1=y1;                          n = 0;
do {
if (n > max) {
System.out.println("no解");
break;
} n++;
c1 = -(f.f(x1)/ f.J(x1)); x1 += c1;                          } while (Math.abs(c1) > eps);
                
                 
System.out.println("n1=" + x1 + " " + "移動距離" + f.fx(x1));
 if ((x1>0)  && (x1<=f.getM()-1 ) && ( f.fx(x1)>0))
   {
   try {
         FileWriter fw=new FileWriter("Newton1"+"-"+x+"-"+y+".txt",true);
         fw.write( y1 + " " + x1 + " " + f.fx(x1) + " " + f.J(x1) + " " + n +"\r\n");
         fw.flush();
         }
         catch (FileNotFoundException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         }
         catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         }
       
   }
}
} private double p; private double m;        double f(double x1) {
          return A1(x1)/m+A1(x1)*A1(x1)/(3*m)+4*A2(x1)/(3*m)
              -A2(x1)*A2(x1)/(3*m)+(1+x1)*A11(x1)/m+2*(1+x1)*A1(x1)*A11(x1)/(3*m)
              +A2(x1)*A11(x1)+A21(x1)/2+5*(1+x1)*A21(x1)/(6*m)+(1+m+x1)*A21(x1)/(2*m)
              +A1(x1)*A21(x1)+2*(1+m-x1)*A2(x1)*A21(x1)/(3*m);
        }        double J(double x1) {
          return 2*A11(x1)/m+4*A1(x1)*A11(x1)/(3*m)
              +2*(1+x1)*A11(x1)*A11(x1)/(3*m)+8*A21(x1)/(3*m)
              -4*A2(x1)*A21(x1)/(3*m)+2*A11(x1)*A21(x1)
              +2*(1+m-x1)*A21(x1)*A21(x1)/(3*m)+(1+x1)*A12(x1)/m
              +2*(1+x1)*A1(x1)*A12(x1)/(3*m)+A2(x1)*A12(x1)+A22(x1)/2
              +5*(1+x1)*A22(x1)/(6*m)+(1+m+x1)*A22(x1)/(2*m)+A1(x1)*A22(x1)
              +2*(1+m-x1)*A2(x1)*A22(x1)/(2*m);
        }
        double fx(double x1) {
                return A1(x1)*A2(x1)+A1(x1)*A1(x1)*(x1+1)/(3*m)
                    +A2(x1)*A2(x1)*(m-x1+1)/(3*m)
                    +A1(x1)*(x1+1)/m
                    +A2(x1)*(x1+m+1)/(2*m)
                    +A2(x1)*(x1+1)/(2*m)
                    +A2(x1)/2+A2(x1)*(x1+1)/(3*m);
        }
        double A1 (double x1) {
        return 1-Math.pow((1-p),x1);
        }
        double A11 (double x1) {
        return -(Math.pow((1-p),x1)*Math.log(1-p));
        }
        double A12 (double x1) {
        return -(Math.pow((1-p),x1)*Math.pow(Math.log(1-p),2));
        }         double A2(double x1) {
          return -Math.pow((1-p),m)+Math.pow((1-p),x1);
         }
         double A21(double x1) {         return Math.pow((1-p),x1)*Math.log(1-p);
         }
         double A22(double x1) {
                  return Math.pow((1-p),x1)*Math.pow(Math.log(1-p),2);
            }
        public double getM() {
                return m;
        }        public void setM(double m) {
                this.m = m;
        }        public double getP() {
                return p;
        }        public void setP(double p) {
                this.p = p;
        }
}

解决方案 »

  1.   


    BigDecimal的pow(int n),
    这个函数只能求整数次方,
    lz的问题有点难度~~
    想办法自己写算法吧~~~~
      

  2.   

    楼主可以将你的类修饰为strictfp,就可以解决问题了。
    strictfp class Newton1{
    ......
    }
      

  3.   

    还是不行,计算结果是一样的。
    当x=18.735584504915433 fx=0.16148753971838095
    当x=18.73558450488718 fx=0.16148753971838095
    明显前后的x是不一样的怎么会得出一样的结果呢
      

  4.   

    我不向给你过多的解释,你用我下面的例子调试一下就明白为什么了,这是数据类型取值范围的问题,你取看一下JAVA基础的数据类型介绍就明白为什么了
    double x=1.2222222222222222222222222222222222222222222;
    float y=(float)1.222222222222222222222222222222222222222;
    BigDecimal z=new BigDecimal("1.2222222222222222222222222222222222");
    System.out.println(x);
    System.out.println(y);
    System.out.println(z);
      

  5.   

    是不是结果不一样
    是你打印出来的结果一样
    System.out.println(...)欺骗了你的眼睛
      

  6.   

    double类型的精度决定了楼主的结果
      

  7.   

    精确计数的话,不要用double进行运算
    用BigDecimal 会达到你想要的
      

  8.   

    楼上的朋友,没看到4楼朋友的回复?BigDecimal也有它的局限性。为什么给分就要结贴?可我的问题还没解决呢?
      

  9.   

    BigDecimal
    复杂小数用这个类试试看
      

  10.   

    这是一个利用牛顿法求fx最小值的问题。
    fx是原方程,但由于这道题的特殊情况,fx直接不能直接用牛顿法,要先求出fx的导数f,再对f用牛顿法。牛顿法是给x1赋一个任意初期值,经过牛顿法的计算得到x1的最小值,再将x1带回到fx里,就能得到fx的最小值。
    写了一大堆,也不知道大家能不能看明白。请多指教:)
      

  11.   

    float和double只推荐用于科学计算如果需要精确计算的话用BigDecimal!
      

  12.   

    要不自己写一个 mydouble 类 呵呵