在while循环之外初始化的变量不会被循环内的代码修改?

时间:2013-06-02 04:24:23

标签: java loops while-loop

在此代码中:

public class PiCalc {
    public static void main(String[] args) {
        double pi = 1.0;
        int n = 3;
        int denominator = 3;
        while (n<10) {
            if (n%2 == 0) {
                pi += 1/denominator;
            }
            else {
                pi -= 1/denominator;
            }
            n++;
            denominator += 2;
        }
        System.out.println(4*pi + "," + n + "," + denominator);
    }
}

输出是: 4.0,10,17

因此,变量n和分母正在按我的意愿更新,但pi不是。谁能告诉我为什么?

3 个答案:

答案 0 :(得分:3)

读到“int division”就像你正在做的那样:

1 / (some int bigger than 1) returns 0

int分割int 的语句必须返回一个int,因此它总是向0舍入。

将其更改为

1.0 / denominator

(double) 1 / denominator

这样你就可以进行双重划分。

答案 1 :(得分:2)

出于最佳实践的考虑,你不应该将denominator从int转换为不断加倍 - 你只是 使用它作为double,所以它应该是一个双重类型的变量。将int加入(或返回)并不是免费的。将denominator变为双精度将更快更容易理解:

public class PiCalc {
    public static void main(String[] args) {
        double pi = 1.0;
        double denominator = 3.0;
        int n = 3;
        while (n<10) {
            if (n%2 == 0) {
                pi += 1.0/denominator;
            }
            else {
                pi -= 1.0/denominator;
            }
            n++;
            denominator += 2.0;
        }
        System.out.println(4*pi + "," + n + "," + denominator);
    }
}

就此而言,如果你要让循环运行超过几个周期(以获得真正准确的pi),你可以通过放弃if来进一步提高性能:

public class PiCalc {
    public static void main(String[] args) {
        double pi = 1.0;
        double denominator = 3.0;
        int n = 3;
        while (n<10000) /* get a really accurate PI */ {
            pi -= 1.0/denominator;
            n++;
            denominator += 2.0;

            pi += 1.0/denominator;
            n++;
            denominator += 2.0;
        }
        System.out.println(4*pi + "," + n + "," + denominator);
    }
}

答案 2 :(得分:1)

1/denominator始终等同于0,因为它们都是int类型 - 就像其他人提到的读取int div一样。您可能希望将两者都转换为double以匹配pi变量。所以我会把if块改成这样的东西。

if (n%2 == 0) {
    pi += 1d/(double)denominator;
} else {
    pi -= 1d/(double)denominator;
}