- 好好學Java:從零基礎到項目實戰
- 歐陽燊
- 2802字
- 2022-07-27 19:14:54
2.4.2 利用割圓術求解圓周率
通過加減乘除的運算迭代求得某數的N次方根,這是意義非凡的數學成就,因為N次方程式據此可以計算出明確的方根數值,從而一舉奠定了代數學的堅實基礎。同時,結合“勾三股四弦五”的勾股定理,能夠使用開平方運算求得直角三角形的斜邊長。假設直角三角形的兩條直角邊分別為a和b,斜邊為c,則有方程式a2+b2=c2 ,由此得到。已知a和b的長度,便能根據牛頓迭代法計算斜邊的長度。不要小看勾股定理及其算法,利用它不但能開展三角函數運算,還能進一步求出圓周率π的數值。
眾所周知,圓周率π是一個無限不循環小數,數學課本上給出的π近似值有3.14和3.1416兩個,它跟勾股定理有什么關系呢?此事說來話長,早在上古時期的中國,人們就認為圓的周長與直徑存在比例關系,當時成書的《周髀算經》中明確記載“圓徑一而周三”,即圓的周長是直徑的三倍(π=3)。后來于漢朝成書的《九章算術》沿用了《周髀算經》里“徑一周三”的說法,當然這個估算的圓周率很不精確,三國時期的劉徽就發現“徑一周三”只適用于圓的內接正六邊形,具體情況如圖2-4所示。
顯然正六邊形的每條邊長外圍還有一段彎曲的圓弧,六段圓弧構成了整個圓圈的周長,由于每段圓弧都比拉直的各邊要長,因此圓周必然大于正六邊形的周長,也就是說圓周率應當比數字3大一些。為了計算出精確的圓周率,劉徽在《九章算術注》中提出了著名的“割圓術”,從圓的內接正六邊形開始,依次往外去割正十二邊形、正二十四邊形等,隨著正N邊形的邊數增加,正N邊形的周長越來越接近圓的周長。正所謂“割之彌細,所失彌少,割之又割,以至于不可割,則與圓周合體而無所失矣?!睘榱烁庇^地理解割圓術的精妙,來看圖2-5所示的圓圈及其內接正六邊形、內接正十二邊形的形狀組合。

圖2-4 圓及其內接正六邊形的周長

圖2-5 圓的內接正六邊形與內接正十二邊形
由圖2-5可見,內接正十二邊形的周長更加接近圓周,從而表明割圓術的理論是正確的。不過內接正十二邊形的邊長該如何計算呢?這個問題必須解決,因為只有求得正N邊形的邊長,才能通過式子“正N邊形的邊長*邊數/直徑”計算出圓周率的近似值。由于內接正六邊形的邊長剛好等于圓的半徑,因此不妨借助于正六邊形計算正十二邊形的邊長。假定圓心為O點,內接正六邊形的某條邊為AB,且線段AB的兩個端點都位于圓圈之上。接著在O點做AB的垂線,且垂線與圓圈相交于C點,與AB相交于D點,此時各點的分布情況如圖2-6所示。

圖2-6 圓的內接正十二邊形的邊長計算
然后分別連接AC兩點與BC兩點,可見線段AC和BC構成了內接正十二邊形的兩條邊長,于是正十二邊形的邊長解法就變成了計算AC或BC的長度。假設圓的半徑長度為r,則線段OA、OB、AB的長度均為r,同時因為垂線OD將三角形OAB二等分,所以線段AD與BD各為AB的一半長即。在直角三角形ODB中,根據勾股定理可知OB2=BD2+OD2,求得
,進一步求得線段CD的長度:
。注意到CDB三點依舊構成直角三角形,那么由勾股定理可得BC2=BD2+CD2,于是得到線段BC的長度:
。倘若r值為1,求得內接正十二邊形的邊長
,此時正十二邊形的周長≈0.5176×12=≈6.212,將這個周長除以圓的直徑長度2,可得正十二邊形對應的圓周率π=6.212/2=3.106。顯而易見,內接正十二邊形的3.106要優于正六邊形的3,要是繼續割到內接正二十四邊形,正二十四邊形對應的圓周率又會比正十二邊形更逼近真實的π值。
上述求解內接正十二邊形邊長的辦法同樣適用于正二十四邊形、正四十八邊形等,中心思想是先二等分每條邊對應的等腰三角形,再連續運用勾股定理依次求得直角三角形的各邊長,進而計算出內接正N邊形的邊長數值。如此每迭代一次運算,正N邊形的邊數就翻倍,反復迭代多次之后,內接正N邊形就越來越趨向于圓圈,相應的圓周率數值也越來越精確。
當年劉徽從圓的內接正六邊形開始,一直割到內接正192邊形,并求得圓周率的近似值為3.14。但他拿官方的度量衡標準容器一驗證,發現3.14還是偏小,于是繼續往上一路割到圓的內接正3072邊形,終于求出此時的圓周率值為3.1416。為了計算準確的圓周率數值,古今中外的眾多數學家窮盡智慧,紛紛各顯神通謀劃圓周,知名的數學家除了劉徽外,還包括東漢數學家張衡、南北朝數學家祖沖之以及古希臘數學家阿基米德、印度數學家阿耶波多、波斯數學家花拉子米、意大利數學家斐波那契、阿拉伯數學家卡西、德國數學家魯道夫、英國數學家牛頓和梅欽等,真可謂“圓周率如此多嬌,引無數天才競折腰”。他們各自推導的圓周率精度見表2-2。
表2-2 古代數學家計算的圓周率紀錄

這些數學家中的佼佼者便是祖沖之,他在劉徽開創的割圓術的基礎上,首次將圓周率推導至小數點后7位,即π值位于3.1415926和3.1415927之間,并且該紀錄保持了近千年才被打破。為了便于日常運算,祖沖之還給出了圓周率的兩個分數形式,其中22/7精確到小數點后兩位,被稱作“約率”;另一個355/113精確到小數點后7位,被稱作“密率”,用于日常生活中的圓周、圓面積、球體積等運算已綽綽有余。
如今來到計算機時代,初學者只要利用割圓術的算法,結合編程語言的四則運算與數學函數,即可不費吹灰之力輕松求得較精確的圓周率值。仍從圓的內接正六邊形開始,依次切割正十二邊形、正二十四邊形直至正三千零七十二邊形,每次切割都根據勾股定理計算出直角三角形的各邊長,且每次迭代過程編寫的算法代碼一模一樣,后續迭代只需將首次的迭代代碼復制粘貼一遍就行,具體的實現示例代碼如下(完整代碼見本章源碼的src\com\arithmetic\Yuanzhoulv.java):
// 假設圓的半徑r=1,則直徑d=2,內接正六邊形的邊長=1 int r=1; // 半徑 long edgeNumber=6L; // 從正六邊形開始內接圓 double edgeLength=r; // 內接正n邊形的邊長(初始值為正六邊形的邊長) double π=edgeLength * edgeNumber / (2*r); // 圓周率 System.out.println("正n邊形的邊數="+edgeNumber+",圓周率="+π); double gou; // 直角三角形中長度最短的邊,稱作“勾” double gu; // 直角三角形中長度居中的邊,稱作“股” // 以下計算內接圓的正十二邊形 edgeNumber=edgeNumber*2; // 正n邊形的邊數乘2 gou=edgeLength/2.0; // 計算勾 gu=r - Math.sqrt(Math.pow(r,2) - Math.pow(gou,2)); // 計算股 // 通過勾股定理求斜邊長(勾三股四弦五),斜邊長也是新正n邊形的邊長 edgeLength=Math.sqrt(Math.pow(gou,2) + Math.pow(gu,2)); // 正n邊形的周長除以直徑,即可得到近似的圓周率數值 π=edgeLength * edgeNumber / (2*r); System.out.println("正n邊形的邊數="+edgeNumber+",圓周率="+π); // 以下計算內接圓的正二十四邊形 edgeNumber=edgeNumber*2; // 正n邊形的邊數乘2 gou=edgeLength/2.0; // 計算勾 gu=r - Math.sqrt(Math.pow(r,2) - Math.pow(gou,2)); // 計算股 // 通過勾股定理求斜邊長(勾三股四弦五),斜邊長也是新正n邊形的邊長 edgeLength=Math.sqrt(Math.pow(gou,2) + Math.pow(gu,2)); // 正n邊形的周長除以直徑,即可得到近似的圓周率數值 π=edgeLength * edgeNumber / (2*r); System.out.println("正n邊形的邊數="+edgeNumber+",圓周率="+π); // 此處省略正四十八邊形、正九十六邊形直到正三千零七十二邊形的代碼
運行以上的圓周率求解代碼,觀察到的輸出日志如下:
正n邊形的邊數=6,圓周率=3.0 正n邊形的邊數=12,圓周率=3.105828541230249 正n邊形的邊數=24,圓周率=3.1326286132812378 正n邊形的邊數=48,圓周率=3.1393502030468667 正n邊形的邊數=96,圓周率=3.14103195089051 正n邊形的邊數=192,圓周率=3.1414524722854624 正n邊形的邊數=384,圓周率=3.141557607911858 正n邊形的邊數=768,圓周率=3.1415838921483186 正n邊形的邊數=1536,圓周率=3.1415904632280505 正n邊形的邊數=3072,圓周率=3.1415921059992717
可見隨著內接正N邊形的邊數增加,求得的圓周率精度越來越高,當n=96的時候,圓周率精確到了3.14,當n=3072的時候,圓周率精確到了小數點后6位。從程序的運行結果可知,史書記載的劉徽割圓之事所言非虛。
- 高手是如何做產品設計的(全2冊)
- DevOps with Kubernetes
- 區塊鏈架構與實現:Cosmos詳解
- Eclipse Plug-in Development:Beginner's Guide(Second Edition)
- MySQL數據庫管理與開發(慕課版)
- 正則表達式經典實例(第2版)
- Mastering ServiceNow(Second Edition)
- D3.js By Example
- Java7程序設計入門經典
- Android智能手機APP界面設計實戰教程
- Learning Cocos2d-JS Game Development
- Java核心編程
- 關系數據庫與SQL Server 2012(第3版)
- Implementing NetScaler VPX?(Second Edition)
- 微信小程序開發圖解案例教程:附精講視頻(第3版)