• 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;
            }
        }

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

  • 相关阅读:
    Springboot源码 bean的注册
    Vue源码之 watch
    Vue源码之 slot
    Vue computed 的嵌套
    Vue的子组件绑定的方法中传入自定义参数
    Vue源码之 Vue的生命周期
    Vue源码之-----computed
    Vue源码之----为什么Vue中Array的pop,push等方法可以reactive,而Array[0]='a'这样的方法不会reactive?
    ReSharper 8.1支持Visual Studio 2013的特色——超强滚动条
    Python开发环境Wing IDE使用教程:部分调试功能介绍
  • 原文地址:https://www.cnblogs.com/yecan/p/10569114.html
Copyright © 2020-2023  润新知