这是我的代码:
import java.math.BigDecimal;
public class Challenge6 {
private static final String PI = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295";
public static BigDecimal calculatePi(int decimals) {
BigDecimal pi = new BigDecimal(3);
boolean toggle = true;
boolean enough = false;
int i = 2;
while (!enough) {
BigDecimal num = new BigDecimal(
(double) (4 / (double) (i * (i + 1) * (i + 2))));
System.out.println(i / 2);
if (toggle) {
pi = pi.add(num);
toggle = false;
} else {
pi = pi.subtract(num);
toggle = true;
}
i += 2;
try {
if (PI.substring(0, decimals + 2).equals(
("" + pi).substring(0, decimals + 2))) {
enough = true;
} else {
}
} catch (Exception ex) {
continue;
}
}
return pi;
}
public static void main(String[] args) {
System.out.printf("Pi: %.30s", calculatePi(10));
}
}
我知道它并不完美,但它只是为了好玩。我只是想知道为什么我的程序可以在700多次迭代中完美地生成最多10个小数位的pi,但是当我尝试计算超过10个时,它会永远(至少我假设永远)。这仅仅是由于浮点除法还是什么?如果是这样,为什么它只是停止在10之后正常工作?此外,如果您在每次迭代打印pi时运行程序,它将变为3.39。 BigDecimal在这里有问题,或者我的代码有问题吗?任何帮助都会很酷。
P.S。 - 我只需要30个小数位。
答案 0 :(得分:0)
你使用BigDecimal类的方式什么都不做。作为双倍的分界(以及分母变大的准确性)将是你的限制因素。
尝试使用BigDecimal组件使用BigDecimal操作进行所有这些操作 - 您可能也希望在分母中使用BigDecimal组件。
实际上你可以将分母变成一个长的并且只使用一个BigNum除法运算直到长时间溢出。我建议不要使用Double或其他任何分母,因为你将无法检测到精度的损失。
答案 1 :(得分:0)
当你使用表达式" new BigDecimal((double)(4 /(double)(i *(i + 1)*(i + 2))))"你使用double,而不是BigDecimal。并且使用双重函数来获得足够的规模来进行超过10位小数的调用。
使用以下代码
public static BigDecimal calculatePi(int decimals) {
BigDecimal pi = new BigDecimal(3);
boolean toggle = true;
boolean enough = false;
int i = 2;
while (!enough) {
BigDecimal a = new BigDecimal(4); // All operation must be using only BigDecimal
BigDecimal b = new BigDecimal(i).multiply(new BigDecimal(i + 1)).multiply(new BigDecimal(i + 2));
BigDecimal num = a.divide(b, 100, RoundingMode.FLOOR);
System.out.println(i / 2);
if (toggle) {
pi = pi.add(num);
toggle = false;
} else {
pi = pi.subtract(num);
toggle = true;
}
i += 2;
if (PI.substring(0, decimals + 2).equals(("" + pi).substring(0, decimals + 2))) {
enough = true;
}
}
return pi;
}
P.S。我检查这个代码的20位小数,但对于30位小数,你需要等待很多时间,我想