Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何创建Exp(-x^2)函数?_Java_Exp - Fatal编程技术网

Java 如何创建Exp(-x^2)函数?

Java 如何创建Exp(-x^2)函数?,java,exp,Java,Exp,我正在使用“思考java”这本书,我被困在练习7.6中。这里的目标是编写一个可以查找的函数。它给了你一些提示: 一种评估方法是 要使用无穷级数展开式,请执行以下操作: 换句话说,我们需要加上一系列的项,其中第i项 等于 这是我提出的代码,但是它对于除1的幂之外的任何东西都是非常错误的(与Math.exp相比)。我不明白为什么,据我所知,代码与书中的公式是正确的。我不确定这更多的是一个数学问题,还是与一个double和int可以容纳多大的数字有关的问题,但我只是想理解为什么这不起作用 p

我正在使用“思考java”这本书,我被困在练习7.6中。这里的目标是编写一个可以查找的函数。它给了你一些提示:

一种评估方法是 要使用无穷级数展开式,请执行以下操作:

换句话说,我们需要加上一系列的项,其中第i项 等于

这是我提出的代码,但是它对于除1的幂之外的任何东西都是非常错误的(与Math.exp相比)。我不明白为什么,据我所知,代码与书中的公式是正确的。我不确定这更多的是一个数学问题,还是与一个double和int可以容纳多大的数字有关的问题,但我只是想理解为什么这不起作用

   public static void main(String[] args) {
      System.out.println("Find exp(-x^2)");
      double x = inDouble("Enter x: ");
      System.out.println("myexp(" + -x*x + ") = " + gauss(x, 20));
      System.out.println("Math.exp(" + -x*x + ") = " + Math.exp(-x*x));
   }

   public static double gauss(double x, int n) {
      x = -x*x;
      System.out.println(x);
      double exp = 1;
      double prevnum = 1;
      int prevdenom = 1;
      int i = 1;
      while (i < n) {
         exp = exp + (prevnum*x)/(prevdenom*i);
         prevnum = prevnum*x;
         prevdenom = prevdenom*i;
         i++;
      }
      return exp;
   } // I can't figure out why this is so inacurate, as far as I can tell the math is accurate to what the book says the formula is

   public static double inDouble(String string) {
      Scanner in = new Scanner (System.in);
      System.out.print(string);
      return in.nextDouble();
   }
publicstaticvoidmain(字符串[]args){
System.out.println(“Find exp(-x^2)”;
double x=inDouble(“输入x:”);
System.out.println(“myexp(“+-x*x+””=“+gauss(x,20));
System.out.println(“Math.exp(“+-x*x+””)=“+Math.exp(-x*x));
}
公共静态双高斯(双x,整数n){
x=-x*x;
系统输出println(x);
双经验=1;
双prevnum=1;
int-prevenom=1;
int i=1;
而(i
我将补充对您问题的评论。我这样做是因为我觉得我有一个稍微好一点的实现

你的方法

您的方法是让函数接受两个参数,其中第二个参数是迭代次数。这还不错,但正如@JamesKPolk所指出的,您可能需要手动搜索不会溢出的int(或long)

我的方法

我的方法将使用称为机器ε的东西作为数据类型。机器ε是该类型中可表示为该数字的最小数字(在您的例子中为double)。如果在
Double
类中“不允许”访问machine epsilon,则存在确定机器epsilon是什么的方法

这背后有数学依据:

函数的级数表示形式为 由于它是交替级数,误差项是您选择不包括的第一项的绝对值(我把证据留给您)

这意味着我们可以有一个不使用迭代的基于错误的实现!最好的部分是,您可以为浮动和“更多”超过两倍的数据类型实现它!我谨此提出:

public static double gauss(double x) 
{
    x = -x*x;
    double exp = 0, error = 1, numerator = 1, denominator = 1;
    double machineEpsilon = 1.0;
    // calculate machineEpsilon
    while ((1.0 + 0.5 * machineEpsilon) != 1.0)
        machineEpsilon = 0.5 * machineEpsilon;
    int n = 0; //
    // while the error is large enough to be representable in terms of the current data type
    while ((error >= machineEpsilon) || (-error <= -machineEpsilon))
    {
        exp += error;
        // calculate the numerator (it is 1 if we just start, but -x times its past value otherwise)
        numerator = ((n == 0) ? 1 : -numerator * x);
        // calculate the denominator (denominator gets multiplied by n)
        denominator *= (n++);
        // calculate error
        error = numerator/denominator;
    }
    return exp;
}
公共静态双高斯(双x)
{
x=-x*x;
双经验=0,误差=1,分子=1,分母=1;
双机械式筒仓=1.0;
//计算机器锡隆
而((1.0+0.5*machineEpsilon)!=1.0)
machineEpsilon=0.5*machineEpsilon;
int n=0//
//而错误大到可以用当前数据类型表示

而((错误>=machineEpsilon)|(-error Java的整数只有32位,而您的
prevdnom
希望最大为19!一个57位的数字。看看当您将
prevdnom
设置为双精度而不是整数时会发生什么。谢谢!效果很好!我想这是有道理的,因为数字太大,所以它不能作为整数工作。允许您这样做吗使用machineEpsilon进行双打?谢谢,这很有效!虽然我花了一些时间才理解它,但它是有意义的