天天看點

開方的幾種寫法

1.牛頓疊代

假設方程 在  附近有一個根,那麼根據f(x)在x0附近的值和斜率,就能估計f(x)和x軸的交點用。疊代式子: 依次計算、、、……,那麼序列将無限逼近方程的根。
用牛頓疊代法開平方】令: 是以f(x)的一次導是: 牛頓疊代式: 随便一個疊代的初始值,例如,代入上面的式子疊代。例如計算,即a=2。 …… 電腦上可給出

根據果殼文章以上闡述,由此我們可以寫出如下代碼:

求9的平方根,嘗試 : 3次 , point : 3 , point的平方 : 9 , point平方與target的內插補點 : 0

到此為此,似乎問題已經得到了圓滿的答案,但緊接着我就發現了更有趣的解法

2.魔法數開方倒數

暴雪是一家神奇的公司,它的代碼總是能給人驚喜,例如 One-way Hash 被業内贊為最優秀的hash表改良算法(timer33算法應該才是最快的,One-way Hash 在Timer33的基礎上改用兩次Hash計算來比對Key是否一緻,在資料結構沒有根本變化的情況下,理論上來說應該更慢)。

下面是暴雪的開平方算法源碼,它對上述的牛頓疊代做了一些改進:

這個算法的牛逼之處在于,經典的牛頓疊代裡猜測值是随便取的一個值,而這段代碼裡卻用了一個魔法數0x5f3759df來作為猜測值。這個算法隻用了一次位運算,根本沒有多次疊代就得到了結果,比直接用sqrt(n)快了大約四倍。

但是,我要說但是了,這個算法并不是暴雪原創的。它更早的時候出現在 雷神之錘3 這個遊戲的3D引擎代碼裡,作者是約翰-卡馬克(John Carmack),江湖人稱卡神。

 注意看代碼

這個魔法數 0x5f3759df 。它是從哪來的,又起到了什麼作用?

單精度的浮點數結構是這樣:
開方的幾種寫法
那麼現在,每個正浮點數 y 可以用尾數和指數的形式寫成 
開方的幾種寫法
,其中 m 是尾數部分,取值範圍是 
開方的幾種寫法
;e 是指數部分,一個整數。每個浮點數所對應的「整數形式」則可以用
開方的幾種寫法
表示,其中 L 是指數部分需要的位移次數(用 2 的幂表示),E 和 M 是指數部分和小數部分的整數版本。兩者之間的關系是
開方的幾種寫法
對單精度浮點而言,
開方的幾種寫法
。 考慮對數 
開方的幾種寫法
,由于
開方的幾種寫法
開方的幾種寫法
,取近似
開方的幾種寫法
,可以算出整體「偏差」最小的
開方的幾種寫法
,此時兩者基本相當。是以我們可以說 
開方的幾種寫法
……………… (1) 那麼,對于 y 的整數形式 Y 而言,展開并帶代入 (1) 有:
開方的幾種寫法
開方的幾種寫法
………………(2) 那麼對于 
開方的幾種寫法
來說,
開方的幾種寫法
,代入 (2) 得:
開方的幾種寫法
解得
開方的幾種寫法

這個就是代碼

的秘密所在。

程式員多學點數學,總是會有用的,與君共勉

附錄:java版算法實作

引用文獻: