标题: 黄金连分数
黄金分割数0.61803… 是个无理数,这个常数十分重要,在许多工程问题中会出现。有时需要把这个数字求得很精确。对于某些精密工程,常数的精度很重要。我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。比较简单的一种是用连分数:
1
黄金数 = ---------------------
1
1 + -----------------
1
1 + -------------
1
1 + ---------
1 + …
这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。
小数点后3位的值为:0.618
小数点后4位的值为:0.6180(注意尾部的0,不能忽略)
你的任务是:写出精确到小数点后100位精度的黄金分割值。
注意:尾数的四舍五入! 尾数是0也要保留!
显然答案是一个小数,其小数点后有100位数字,请通过浏览器直接提交该数字。
思路:
动笔算一算,发现规律,发现这不就是Fibonacci数列吗?
1.转换为求斐波那契数列相邻两项,但是到第几项呢?
越多越精确,n/n+1项,n要满足的条件:n再往上增加,这个比值的小数点后101位是稳定的,也就是不变的
2.double无法表示100位的小数,需要用到大数运算BigInteger和BigDecimal
public class Test {
public static void main(String[] args) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
// int aa = 1, bb = 1, r = 3;
// while (r < 300) {
// int cc = aa + bb;
// aa = bb;
// bb = cc;
// }
// int ans =aa/bb;
for (int i = 3; i < 500; i++) {
BigInteger temp = a.add(b);
a = b;
b = temp;
}
BigDecimal ans = new BigDecimal(a, 110).divide(new BigDecimal(b, 110), BigDecimal.ROUND_HALF_DOWN);
System.out.println(ans.toPlainString().substring(0, 103));
}
}
方法解析:
- BigDecimal.ROUND_HALF_DOWN最贴切的说法应该是叫五舍六入,舍弃的部分如果大于5才进位,小于或等于5直接舍弃。
- String toPlainString() ——Returns a string representation of this BigDecimal without an exponent field. (an exponent field. 指数域)
- String toString() ——Returns the string representation of this BigDecimal, using scientific notation if an exponent is needed.
- toString()在某些情况下显示数值会变为科学计数法,而toPlainString()始终精确显示数值本身。
得好好思考思考。所以这用toPlainString()。 - public String substring(int beginIndex, int endIndex )——返回一个字符串子串[ beginIndex,endIndex-1]。这样子串的长度是 endIndex-beginIndex。
这里时从0开始截取子串,截取到小数点后101位,加上小数点和小数点前的0,一共103位。
因为题目要求的是100位,所以求出来的答案最后一位要进行四舍五入!!
最终答案:
0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113745
end.