使用 Java 的莱布尼茨公式
Leibniz Formula using Java
圆周率的莱布尼茨公式是:pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9...我想在 Java 中写这个但是 运行 遇到了输出始终为 4(这不是 pi 的值)的问题。我将我的代码放在 java 可视化工具中,问题似乎是当代码落入 else 语句时,它不是从 pi 中减去(1 分母),而是生成 prevPi 值和 pi值与导致 do/while 循环结束的值相同。有谁知道我该如何解决这个问题?
我的代码:
public static float piCalculatorLeibniz() {
float pi = 0;
int denominator = 1;
float prevPi = 0;
boolean keepGoing = true;
int i = 0;
while (keepGoing == true) {
prevPi = pi;
if (i % 2 == 0) {
pi += (1/denominator);
} else {
pi -= (1/denominator);
}
i++;
denominator += 2;
if (pi == prevPi) {
keepGoing = false;
}
}
pi *= 4;
return pi;
}
让你的,所有你的操作数都是浮点类型。否则你的结果是一个整数。
参见Java Language Specifications:
If the promoted type is float or double, then floating-point arithmetic is performed.
此外,在大多数平台上,您可以使用 double 而不会造成任何性能损失,但这是另一个话题。 ;-)
你是对的。 4其实不是Pi的值。
问题是 denominator
变量是 int
所以 1/denomenator
是 int/int
所以结果是 0
。自 pi == prevPi
以来,这使您仅在一次迭代后就退出循环
只需将 denominator
类型更改为双精度(或浮点型),您就会得到正确的答案。
还有,你不需要写while(keepGoing == true)
。变量 keepGoing
已经是一个布尔值,你可以简单地写成 while(keepGoing)
编辑:
我喜欢玩这段代码,所以这里有一个稍微短一点的版本,由于使用了 double
,它更准确。它似乎也收敛得更快:
double pi = 0, denominator = 1, prevPi = 1;
while (pi != prevPi) {
prevPi = pi;
pi += (1 / denominator) - (1 / (denominator + 2));
denominator += 4;
}
return pi * 4;
问题是整数除法得到的是整数,而不是浮点数或双精度数。
1 / 3
为 0。
为避免这种情况,您可以改用浮点数而不是整数作为分母。
float denominator = 1.0f;
圆周率的莱布尼茨公式是:pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9...我想在 Java 中写这个但是 运行 遇到了输出始终为 4(这不是 pi 的值)的问题。我将我的代码放在 java 可视化工具中,问题似乎是当代码落入 else 语句时,它不是从 pi 中减去(1 分母),而是生成 prevPi 值和 pi值与导致 do/while 循环结束的值相同。有谁知道我该如何解决这个问题?
我的代码:
public static float piCalculatorLeibniz() {
float pi = 0;
int denominator = 1;
float prevPi = 0;
boolean keepGoing = true;
int i = 0;
while (keepGoing == true) {
prevPi = pi;
if (i % 2 == 0) {
pi += (1/denominator);
} else {
pi -= (1/denominator);
}
i++;
denominator += 2;
if (pi == prevPi) {
keepGoing = false;
}
}
pi *= 4;
return pi;
}
让你的,所有你的操作数都是浮点类型。否则你的结果是一个整数。
参见Java Language Specifications:
If the promoted type is float or double, then floating-point arithmetic is performed.
此外,在大多数平台上,您可以使用 double 而不会造成任何性能损失,但这是另一个话题。 ;-)
你是对的。 4其实不是Pi的值。
问题是 denominator
变量是 int
所以 1/denomenator
是 int/int
所以结果是 0
。自 pi == prevPi
只需将 denominator
类型更改为双精度(或浮点型),您就会得到正确的答案。
还有,你不需要写while(keepGoing == true)
。变量 keepGoing
已经是一个布尔值,你可以简单地写成 while(keepGoing)
编辑:
我喜欢玩这段代码,所以这里有一个稍微短一点的版本,由于使用了 double
,它更准确。它似乎也收敛得更快:
double pi = 0, denominator = 1, prevPi = 1;
while (pi != prevPi) {
prevPi = pi;
pi += (1 / denominator) - (1 / (denominator + 2));
denominator += 4;
}
return pi * 4;
问题是整数除法得到的是整数,而不是浮点数或双精度数。
1 / 3
为 0。
为避免这种情况,您可以改用浮点数而不是整数作为分母。
float denominator = 1.0f;