文章目录
黄金连分数
黄金分割数0.61803是个无理数,这个常数十分重要,在许多工程问题中会出现。有时需要把这个数字求得很精确。我们如何求得黄金分割数的尽可能精确的值呢?
比较简单的一种是用连分数:
1
黄金数 = ------------------------
1
1 + ------------------
1
1 + -----------
1
1 + ------
1+…
这个连分数计算的“层数”越多,它的值越接近黄金分割数。
小数点后3位的值为:0.618
小数点后4位的值为:0.6180
小数点后5位的值为:0.61803
小数点后7位的值为:0.6180340
你的任务是:写出精确到小数点后100位精度的黄金分割值
注意:尾数的四舍五入/尾数是0也要保留!
请你利用这一特性,求出黄金分割数的足够精值,要求四舍五入到小数点后100位
- 经过几个例子的试探,可以发现连分数的计算结果与斐波那契数列很是相似。这样一来结果就可以化成:
求斐波那契数列相邻两个数的比值
public class Test02_2013黄金连分数 {
public static void main(String[] args) {
// 声明两个变量用来存储相邻的两个数
double a = 1.0;
double b = 1.0;
for (int i = 3; i < 100; i++) {
double t = b;
b = a+b;
a = t;
}
System.out.println(a/b);
}
}
0.6180339887498948
显然,结果出来是黄金比例数。但是结果的小数位数并不满足题目要求,我继续将i的取值扩大到300,结果如下图:
可以看到结果的小数位数并没有改变,这是因为double浮点型数最小保留至小数点后16位
,所以其精确度不能够满足条件。
为了满足大数据的计算,我们可以使用到java中的BigInteger
和BigDecimal
。
通过使用高精度的API进行计算后,得出的结果应当是小数点后101位,然后四舍五入为100位。
上面曾说过:连分数计算的“层数”越多,它的值越接近黄金分割数。所以在这里我们通过增加i的上限,变向的来提高精度
。在测试的时候可以发现i>300
之后,前100位的数基本就固定不变了。
public static void main(String[] args) {
// 声明两个变量用来存储相邻的两个数
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
for (int i = 3; i < 300; i++) {
BigInteger t = b;
b = a.add(b); // BigInteger中数字相加用add()
a = t;
}
// 将整型数转为高精度浮点数
// 除的时候用divide()
BigDecimal divide = new BigDecimal(a,110).divide(new BigDecimal(b,110), BigDecimal.ROUND_HALF_DOWN);
// 输出的时候将其转为字符串,连“0.”,共103位
System.out.println(divide.toPlainString().substring(0,103));
}
0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
最终结果:
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375