亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

基于John Carmark密碼詳解

2020-01-26 16:17:14
字體:
來源:轉載
供稿:網友

有人在Quake III的源代碼里面發現這么一段用來求平方根的代碼:

/*================SquareRootFloat================*/

float SquareRootFloat(float number) {
    long i;
    float x, y;
    const float f = 1.5F;
    x = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;
    i  = 0x5f3759df - ( i >> 1 );  //注意這一行
    y  = * ( float * ) &i;
    y  = y * ( f - ( x * y * y ) );
    y  = y * ( f - ( x * y * y ) );
    return number * y;
}

x5f3759df? 這是個什么東西? 學過數值分析就知道,算法里面求平方根一般采用
的是無限逼近的方法,比如牛頓迭代法,抱歉當年我數值分析學的太爛,也講不清楚
。簡單來說比如求5的平方根,選一個猜測值比如2,那么我們可以這么算

/2 = 2.5; 2.5+2/2 = 2.25; 5/2.25 = xxx; 2.25+xxx/2 = xxxx ...
這樣反復迭代下去,結果必定收斂于sqrt(5),沒錯,一般的求平方根都是這么算的
。而卡馬克的不同之處在于,他選擇了一個神秘的猜測值0x5f3759df作為起始,使得
整個逼近過程收斂速度暴漲,對于Quake III所要求的精度10的負三次方,只需要一
次迭代就能夠得到結果。

好吧,如果這還不算牛b,接著看。

普渡大學的數學家Chris Lomont看了以后覺得有趣,決定要研究一下卡馬克弄出來的
這個猜測值有什么奧秘。Lomont也是個牛人,在精心研究之后從理論上也推導出一個
最佳猜測值,和卡馬克的數字非常接近, 0x5f37642f??R克真牛,他是外星人嗎?


傳奇并沒有在這里結束。Lomont計算出結果以后非常滿意,于是拿自己計算出的起始
值和卡馬克的神秘數字做比賽,看看誰的數字能夠更快更精確的求得平方根。結果是
卡馬克贏了... 誰也不知道卡馬克是怎么找到這個數字的。

最后Lomont怒了,采用暴力方法一個數字一個數字試過來,終于找到一個比卡馬克數
字要好上那么一丁點的數字,雖然實際上這兩個數字所產生的結果非常近似,這個暴
力得出的數字是0x5f375a86。

Lomont為此寫下一篇論文,"Fast Inverse Square Root"。

我把這個函數用C#就行了一下改寫:

復制代碼 代碼如下:

using System;
 using System.Collections.Generic;
 using System.Text;

 namespace ConsoleApplication1
 {
     class Program
     {
         static void Main(string[] args)
        {
            Console.WriteLine("Carmark's method:");
            Console.WriteLine(SquareRootFloat(3.0f).ToString());
            Console.WriteLine("Use Math.Sqrt() method:");
            Console.WriteLine(((float)Math.Sqrt(3.0)).ToString());
            Console.Read();
        }

        private static float SquareRootFloat(float number)
        {

            long i;
            float x, y;
            const float f = 1.5F;
            x = number * 0.5F;
            y  = number;
            unsafe
            {
                i  = * ( long * ) &y;
                i  = 0x5f3759df - ( i >> 1 );  //注意這一行
                y  = * ( float * ) &i;
            }
            y  = y * ( f - ( x * y * y ) );
            y  = y * ( f - ( x * y * y ) );
            return number * y;
        }
    }
}


 第32、33行用了兩次牛頓迭代法,以達到一定的精度,當然你也可以自己控制精度,求出來的是y的平方根的倒數,所以最后返回為number*y.

SquareRootFloat函數最關鍵的一句就是 i=0x5f3759df-(i>>1);
以下是對它的部分解釋:

牛頓迭代法最關鍵的地方在于估計第一個近似根。如果該近似根與真根足夠靠近的話,那么只需要少數幾次迭代,就可以得到滿意的解。

接著,我們要設法估計第一個近似根。這也是上面的函數最神奇的地方。它通過某種方法算出了一個與真根非常接近的近似根,因此它只需要使用一次迭代過程就獲得了較滿意的解。它是怎樣做到的呢?所有的奧妙就在于這一行:

i = 0x5f3759df - (i >> 1); // 計算第一個近似根

超級莫名其妙的語句,不是嗎?但仔細想一下的話,還是可以理解的:float類型的數據在32位系統上是這樣表示的。

bits:31 30 ... 031:符號位30-23:共8位,保存指數(E)22-0:共23位,保存尾數(M)

所以,32位的浮點數用十進制實數表示就是:M*2^E。開根然后倒數就是:M^(-1/2)*2^(-E/2)?,F在就十分清晰了。語句i>>1其工作就是將指數除以2,實現2^(E/2)的部分。而前面用一個常數減去它,目的就是得到M^(1/2)同時反轉所有指數的符號。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品亚洲一区二区三区在线播放| 国产日韩专区在线| 国产日韩精品在线播放| 欧美视频专区一二在线观看| 姬川优奈aav一区二区| 一区二区欧美日韩视频| 91亚洲午夜在线| 国产国语videosex另类| 在线观看久久av| 亚洲毛片在线观看| 91精品久久久久久久久久久久久| 亚洲第一综合天堂另类专| 亚洲精品美女在线观看播放| 国产乱人伦真实精品视频| 精品国产一区二区三区久久久狼| 自拍偷拍免费精品| 96pao国产成视频永久免费| 国产精品久久久久久网站| 欧美性猛交丰臀xxxxx网站| 欧美日韩成人黄色| 欧美午夜无遮挡| 中文字幕欧美国内| 欧美日韩在线另类| 日韩国产高清视频在线| 欧美日韩黄色大片| 日韩黄色在线免费观看| 成人av资源在线播放| 亚洲一区二区三区毛片| 日韩精品免费视频| 日韩av影院在线观看| 国产精品视频永久免费播放| 亚洲天堂av女优| 欧美日本黄视频| 国产亚洲视频在线| 亚洲欧美精品中文字幕在线| 精品久久中文字幕| 一区二区三区国产在线观看| 日韩经典中文字幕| 成人精品福利视频| 久久天天躁狠狠躁夜夜av| 久久网福利资源网站| 成人免费淫片aa视频免费| 久久99亚洲热视| 亚洲少妇激情视频| 欧美性20hd另类| 九九热精品视频国产| 亚洲欧美综合v| 国产精品一久久香蕉国产线看观看| 国产aaa精品| 影音先锋欧美在线资源| 亚洲最大的av网站| 国产精品永久免费视频| 国产精品女人久久久久久| 欧美极品少妇xxxxⅹ免费视频| 日本成熟性欧美| 国产精品女主播| 欧美丰满少妇xxxx| 国产一区二区三区在线观看视频| 亚洲美女视频网| 日韩综合中文字幕| 日韩在线视频中文字幕| 国产精品88a∨| 久久国产精品亚洲| 欧美日韩成人免费| 欧美一区二区影院| 亚洲成色999久久网站| 国产精品va在线播放我和闺蜜| 97在线观看免费高清| 美女福利视频一区| 91国语精品自产拍在线观看性色| 日本国产欧美一区二区三区| 国产精品一区久久久| 亚洲老头同性xxxxx| 精品magnet| 欧美性猛交xxxx黑人| 最近2019中文字幕第三页视频| 亚洲激情免费观看| 国产伦精品一区二区三区精品视频| 一区二区三区四区精品| 不卡毛片在线看| 国产精品免费久久久久久| 国产精品三级久久久久久电影| 精品中文视频在线| 成人在线观看视频网站| 九九精品视频在线观看| 国产在线高清精品| 日韩小视频网址| 久久91精品国产91久久久| 国产精品爽黄69| 久久精品国产成人| 国产成人精品在线播放| 在线观看视频99| 欧美在线日韩在线| 亚洲欧美999| 国产日韩欧美视频在线| 上原亚衣av一区二区三区| 日韩av大片在线| 91精品国产亚洲| 亚洲四色影视在线观看| 精品国产一区二区在线| 亚洲一区国产精品| 欧美激情欧美狂野欧美精品| 色视频www在线播放国产成人| 欧美噜噜久久久xxx| 亚洲视频自拍偷拍| 精品无人国产偷自产在线| 日韩中文字幕在线播放| 精品久久久久久亚洲国产300| 亚洲精品一区av在线播放| 深夜精品寂寞黄网站在线观看| 日韩精品中文字幕有码专区| 91夜夜揉人人捏人人添红杏| 亚洲奶大毛多的老太婆| 亚洲国产天堂久久综合| 亚洲最大的成人网| 欧美日在线观看| 午夜精品国产精品大乳美女| 欧美乱人伦中文字幕在线| 成人免费视频在线观看超级碰| 国产午夜精品全部视频播放| 色综合色综合网色综合| 欧美一级bbbbb性bbbb喷潮片| 北条麻妃一区二区三区中文字幕| 久久国产精品亚洲| 久久久亚洲网站| 欧美激情亚洲综合一区| 国产精品无码专区在线观看| 久久精品成人欧美大片| 久久精品视频va| 亚洲精品视频网上网址在线观看| 久久中文精品视频| 亚洲国产精久久久久久久| 日韩美女视频免费在线观看| 国产精品极品在线| 久久综合伊人77777蜜臀| 日韩欧美在线免费观看| 日本高清久久天堂| 精品高清一区二区三区| 成人在线一区二区| 亚洲欧美日韩中文在线制服| 亚洲第一天堂无码专区| 国产91热爆ts人妖在线| 国产综合在线视频| 久久久久久中文字幕| 国产精品a久久久久久| 久久久久一本一区二区青青蜜月| 国产日韩精品在线观看| 中文.日本.精品| 欧美在线一级视频| 国产精品普通话| 伊人久久男人天堂| 久久久精品网站| 亚洲精品一区中文| 成人在线视频网| 在线观看视频99| 91精品国产综合久久男男| 国产精品7m视频| 成人精品久久久| 一区二区日韩精品| 国产午夜精品麻豆| 亚洲第一免费播放区| 久久91精品国产91久久跳| 日本中文字幕久久看| 福利精品视频在线|