zoukankan      html  css  js  c++  java
  • 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;
            }
        }

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

  • 相关阅读:
    Linux下Subversion的使用
    python3之HTML、CSS学习
    Python成长之路 常用模块与正则表达式
    Css3 列表布局 两列或者多列布局整理
    .net 通过代码控制GridView显示列
    .net 创建一个页面级全局datatable的方法
    .net 将分页展示的GridView的全部数据 导出excel
    .net 如何判断dataset是否为空
    sql 全表结构备份
    sql 把一个表中的某一列赋值到另一个表中的某一列
  • 原文地址:https://www.cnblogs.com/yecan/p/10569114.html
Copyright © 2011-2022 走看看