Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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 如何将digamma函数重写为非递归函数_Java_Stack Overflow - Fatal编程技术网

Java 如何将digamma函数重写为非递归函数

Java 如何将digamma函数重写为非递归函数,java,stack-overflow,Java,Stack Overflow,我运行了一个java程序,得到了一个stackoverflow错误,这个错误是由a引起的,代码是 public static double digamma(double x) { if (x >= 0 && x < GAMMA_MINX) { x = GAMMA_MINX; } if (x < DIGAMMA_MINNEGX) { return digamma(DIGAMMA_MINNEGX + GAMMA

我运行了一个java程序,得到了一个
stackoverflow错误
,这个错误是由a引起的,代码是

public static double digamma(double x) {
    if (x >= 0 && x < GAMMA_MINX) {
        x = GAMMA_MINX;
    }
    if (x < DIGAMMA_MINNEGX) {
        return digamma(DIGAMMA_MINNEGX + GAMMA_MINX);
    }
    if (x > 0 && x <= S_LIMIT) {
        return -GAMMA - 1 / x;
    }

    if (x >= C_LIMIT) {
        double inv = 1 / (x * x);
        return Math.log(x) - 0.5 / x - inv
                * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252));
    }
    return digamma(x + 1) - 1 / x;
}

由于
stackoverflow错误
是由于递归级别太深,以至于超出了线程的堆栈大小(对吗?),因此我将
Xss
参数增加到
20M
,但错误仍然存在,因此我认为必须将其重写为非递归,但我没有将递归函数重新编译为非递归函数的经验。

未经测试,但它是:

public static double digamma(double x) {

    double value = 0;

    while (true){

        if (x >= 0 && x < GAMMA_MINX) {
            x = GAMMA_MINX;
        }
        if (x < DIGAMMA_MINNEGX) {
            x = DIGAMMA_MINNEGX + GAMMA_MINX;
            continue;
        }
        if (x > 0 && x <= S_LIMIT) {
            return value + -GAMMA - 1 / x;
        }

        if (x >= C_LIMIT) {
            double inv = 1 / (x * x);
            return value + Math.log(x) - 0.5 / x - inv
                    * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252));
        }

        value -= 1 / x;
        x = x + 1;
    }

}
public静态双数字放大器(双x){
双值=0;
while(true){
如果(x>=0&&x0&&x=C_极限){
双投资=1/(x*x);
返回值+数学日志(x)-0.5/x-库存
*((1.0/12)+inv*(1.0/120-inv/252));
}
值-=1/x;
x=x+1;
}
}
因为代码几乎是尾部递归的,所以技巧是在整个主体上抛出一个循环


捕捉的是结尾处的
-1/x
。但是,由于它是加法的,所以在开始下一次迭代之前,您可以从结果中减去
1/x

您不希望
返回
在循环之外,并在正文中包含某种
中断
语句吗?这只是风格的问题。否则就没关系了。(除非Java抱怨缺少返回状态。)感谢您的帮助。我看到还有一个递归函数调用在<代码> DigaMa(DigaMaMIN NIGNXX+GAMMAYMIX),所以这不是一个纯非递归版本,那么有没有办法将它改写成纯非递归版本?我忽略了中间调用。我会看看我是否也能摆脱它。实际上,
digamma(digamma\u MINNEGX+GAMMA\u MINX)
只是一个常数。你不能预先计算并完全替换它吗?
public static double digamma(double x) {

    double value = 0;

    while (true){

        if (x >= 0 && x < GAMMA_MINX) {
            x = GAMMA_MINX;
        }
        if (x < DIGAMMA_MINNEGX) {
            x = DIGAMMA_MINNEGX + GAMMA_MINX;
            continue;
        }
        if (x > 0 && x <= S_LIMIT) {
            return value + -GAMMA - 1 / x;
        }

        if (x >= C_LIMIT) {
            double inv = 1 / (x * x);
            return value + Math.log(x) - 0.5 / x - inv
                    * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252));
        }

        value -= 1 / x;
        x = x + 1;
    }

}