sqrt开平方算法的尝试,是的看了卡马克大叔的代码,我来试试用C#写个0x5f3759df和0x5f375a86跟System.Math.Sqrt到底哪个更强

Posted yecan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqrt开平方算法的尝试,是的看了卡马克大叔的代码,我来试试用C#写个0x5f3759df和0x5f375a86跟System.Math.Sqrt到底哪个更强相关的知识,希望对你有一定的参考价值。

 

今天笔试遇到一个代码题,要求写一个开平方算法,回来发现了雷神之锤里的一段神代码:

 1 float Q_rsqrt( float number )
 2 {
 3     long i;
 4     float x2, y;
 5     const float threehalfs = 1.5F;
 6     x2 = number * 0.5F;
 7     y   = number;
 8     i   = * ( long * ) &y;   // evil floating point bit level hacking
 9     i   = 0x5f3759df - ( i >> 1 ); // what the fuck?
10     y   = * ( float * ) &i;
11     y   = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
12     // y   = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
13 
14     #ifndef Q3_VM
15     #ifdef __linux__
16          assert( !isnan(y) ); // bk010122 - FPE?
17     #endif
18     #endif
19     return y;
20 } 

 

打算用C#写一个,试试这玩意会有多好用。

    class Sqrt_Yc
    {
        unsafe internal static double DoubleSqrt(double number)
        {
            double x2, y;
            const double threehalfs = 1.5F;
            Int64 i;
            x2 = number * 0.5F;
            i = *(Int64*)&number;
            i = 0x5fe6ec85e7de30da - (i >> 1);//
            y = *(double*)&i;
            y = y * (threehalfs - (x2 * y * y)); 
            y = y * (threehalfs - (x2 * y * y));
            return 1 / y;
        }

        unsafe internal static float SingleSqrt0x5f375a86(float number)
        {
            int i;
            float x2, y;
            const float threehalfs = 1.5F;
            x2 = number * 0.5F;
            y = number;
            i = *(int*)&y;   // evil floating point bit level hacking
            i = 0x5f375a86 - (i >> 1); // Chris Lomont‘s number
            y = *(float*)&i;
            y = y * (threehalfs - (x2 * y * y)); 
            return 1/y;
        }

        unsafe internal static float SingleSqrt0x5f3759df(float number)
        {
            int i;
            float x2, y;
            const float threehalfs = 1.5F;
            x2 = number * 0.5F;
            y = number;
            i = *(int*)&y;   // evil floating point bit level hacking
            i = 0x5f3759df - (i >> 1); // John Carmack‘s number
            y = *(float*)&i;
            y = y * (threehalfs - (x2 * y * y));
            return 1 / y;
        }

        //意外收获,C#中定义联合体的方法,虽然和本内容无关
        [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
        public struct Double_Long_UNION
        {
            [FieldOffset(64)]
            internal Int64 intNum;

            [FieldOffset(64)]
            internal double doubleNum;
        }
    }

列位可以自己调用尝试下,今天收获不小,向先人致敬。

 

以上是关于sqrt开平方算法的尝试,是的看了卡马克大叔的代码,我来试试用C#写个0x5f3759df和0x5f375a86跟System.Math.Sqrt到底哪个更强的主要内容,如果未能解决你的问题,请参考以下文章

c语言实现求解这样的6位数:SQRT(6位数)=3位数,9个数字互不相同(SQRT表示开平方)

C语言中开平方函数是啥?

go 牛顿法开平方

QT的开平方函数是啥呀?

sqrt函数实现之卡马克方法

用 逻辑电路 实现一个 开平方 算法