1.第一种方法:二分法
BigDecimal eps=new BigDecimal(1e-125);
BigDecimal now=new BigDecimal(5);
BigDecimal get() {
BigDecimal l=new BigDecimal("0");
BigDecimal r=new BigDecimal("3");
while(l.add(eps).compareTo(r)<=0) {
BigDecimal mid=l.add(r).divide(BigDecimal.valueOf(2));
if(mid.multiply(mid).compareTo(now)<=0) {
l=mid;
}
else {
r=mid;
}
}
return l;
}
上面的代码可以精确125位,求根号5,求其他的类似。
第二种方法:牛顿迭代法
主要就是一直求着个式子灵魂画师。
//也是求根号5的 y=x^2-5;导数是2*x
BigDecimal eps=new BigDecimal(1e-125);
BigDecimal now=new BigDecimal(5);
BigDecimal get() { //牛顿迭代法 求解根号5
BigDecimal res=null;
for(int i=1;i<=120;i++) {
BigDecimal t=now.multiply(now).subtract(BigDecimal.valueOf(5));
res=now.subtract(t.divide (now.multiply(BigDecimal.valueOf(2)),130,BigDecimal.ROUND_DOWN) );
now=res;
}
return res;
}
还有一点值得注意,
res=now.subtract(t.divide (now.multiply(BigDecimal.valueOf(2))));
如果for循环中的第二行这么写,会报下面错误,这是因为高精浮点数精确位数的问题,可以像上面一样设置三个参数。第二个参数是精确位数,后面的是精确方式,当然越多越好,前提不爆内存。
Non-terminating decimal expansion; no exact representable decimal result.
2016大连icpc的大数搬威佐夫博弈,可以去尝试一下,题目就是要求出黄金分割比精确的一百多位。