标题: 黄金连分数
黄金分割数0.61803… 是个无理数,这个常数十分重要,在许多工程问题中会出现。有时需要把这个数字求得很精确。
对于某些精密工程,常数的精度很重要。也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,却使它成了“近视眼”!!
言归正传,我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。
比较简单的一种是用连分数:
这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。
小数点后3位的值为:0.618 小数点后4位的值为:0.6180 小数点后5位的值为:0.61803 小数点后7位的值为:0.6180340
(注意尾部的0,不能忽略)
你的任务是:写出精确到小数点后100位精度的黄金分割值。
注意:尾数的四舍五入! 尾数是0也要保留!
显然答案是一个小数,其小数点后有100位数字,请通过浏览器直接提交该数字。 注意:不要提交解答过程,或其它辅助说明类的内容。
分析:
当这个连分数只有一层时,为1/(1+1)=1/2
2层,1/(1+1/2)=2/3
3层,1/(1+2/3)=3/5
…………
不难推出后面的分数依次是5/8、8/13、13/21………………
仔细观察,我们不难发现,这个分数的每一项都是斐波那挈数列(1,1,2,3,5,8,13,21………………)中相邻两项的比值。
所以这个题化为求斐波那契数列中相邻两项的比值。
题目要求精确到小数点后100位精度的黄金分割值,用普通的int 型或者double无法表示100位小数,所以要用到BigInteger和BigDecimal。
还有个问题,什么时候才够精确呢?
能够表示出100位小数的时候就是精确的吗?
当然不是。
当然是项数越多越精确,当n/n+1项,n再往上增加,这个比值的小数点后101位是稳定的,也就是不变的,我们可以认为此时前100位是精确的了。
代码:
import java.math.BigDecimal;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger a = BigInteger.ONE;//1
BigInteger b = BigInteger.ONE;//1
//斐波那契数列的迭代形式
for (int i = 3; i < 300; i++) {
BigInteger tmp = b;
b = a.add(b);
a = tmp;
}
//大浮点数的除法
BigDecimal divide = new BigDecimal(a,110).divide(new BigDecimal(b,110), BigDecimal.ROUND_HALF_DOWN);
//截取字符串,包括0和小数点共103位,即小数点后有101位
System.out.println(divide.toPlainString().substring(0,103));
}
}
我们可以在for循环中,对i的值进行试探,以此来确定小数点后101位是否稳定是稳定的。
当i<200时,
0.61803398874989484820458683436563811772030917980576286213544862270526046281890244969233401224637257135
当i<300时,
0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
当i<400时,
0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
可见i> 300之后,输出结果的101位已经趋于稳定,四舍五入之后,答案应该是
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375
-
BigDecimal简介
BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue × 10-scale)。 -
public String toPlainString()
返回不带指数字段的此 BigDecimal 的字符串表示形式。