題目描述
黃金分割數 0.61803… 是個無理數,
這個常數十分重要,在許多工程問題中會出現。有時需要把這個數字求得很精確。
對於某些精密工程,常數的精度很重要。也許你聽說過哈勃太空望遠鏡,它首次升空後就發現了一處人工加工錯誤,
對那樣一個龐然大物,其實只是鏡面加工時有比頭髮絲還細許多倍的一處錯誤而已,卻使它成了 “近視眼”!!
言歸正傳,我們如何求得黃金分割數的儘可能精確的值呢?有許多方法。
比較簡單的一種是用連分數:
這個連分數計算的 “層數” 越多,它的值越接近黃金分割數。
請你利用這一特性,求出黃金分割數的足夠精確值,要求四捨五入到小數點後 100 位。
小數點後3位的值爲:0.618
小數點後4位的值爲:0.6180
小數點後5位的值爲:0.61803
小數點後7位的值爲:0.6180340
(注意尾部的0,不能忽略)
你的任務是:寫出精確到小數點後 100 位精度的黃金分割值。
注意:尾數的四捨五入! 尾數是 0 也要保留!
顯然答案是一個小數,其小數點後有 100 位數字,請通過瀏覽器直接提交該數字。
注意:不要提交解答過程,或其它輔助說明類的內容。
思路
首先看到這道題,我們很容易聯想到使用遞歸來完成,但是仔細一想,用遞歸在描述代碼的過程可能比較麻煩,除了遞歸,還可以使用像斐波那契那樣的非遞歸算法完成,在分析黃金分割數的規律之後,會發現它符合像斐波那契數列那樣,可以對其前一項和前前一項進行比值,也可以得到答案,這裏不再細說。
這裏我採用了一種更加簡單的方法,直接觀察上面式子的特點,根據四則運算就可以很快的得出答案,下面放出代碼:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class 黃金連分數 {
public static void main(String[] args) {
BigDecimal bigdouble = new BigDecimal(1);
BigDecimal one=new BigDecimal(1);
for (int i = 0; i < 300; i++) {
bigdouble=one.divide(bigdouble,100,BigDecimal.ROUND_HALF_UP);
bigdouble=bigdouble.add(one);
}
bigdouble=one.divide(bigdouble,100,BigDecimal.ROUND_HALF_UP);
System.out.println(bigdouble);
}
}
注意點解析
- 通過對題目給出的式子分析後,用下面的式子就可解出答案:
sum=1.0/sum+1.0;
sum=1/sum;
-
在這裏我們不能用double來描述這兩條式子,因爲題目要求精確到小數點後100位,而double做不到這一點,所以我們要用到BigDecimal類。
-
for循環的時候,我先是讓i循環1000次,然後輸出,分析結果,再往下減少i的次數,最終取300爲最終結果,不斷調整i的次數是爲了尋找一個穩定的數值。
-
這裏在參數取100即表示小數點後100位,因爲第三個參數RoundingMode.HALF_UP設置了對數值進行四捨五入了。