是否有可能用C#地震的快速InvSqrt()函数? [英] Is it possible to write Quake's fast InvSqrt() function in C#?

查看:161
本文介绍了是否有可能用C#地震的快速InvSqrt()函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是只是为了满足自己的好奇心。

This is just to satisfy my own curiosity.

有没有这方面的一个实现:

Is there an implementation of this:

float InvSqrt (float x)
{
   float xhalf = 0.5f*x;
   int i = *(int*)&x;
   i = 0x5f3759df - (i>>1);
   x = *(float*)&i;
   x = x*(1.5f - xhalf*x*x);
   return x;
}

在C#?如果它存在,职位的代码。

in C#? If it exists, post the code.

我想我应该提到我一直在寻找一个安全的实施......无论哪种方式,BitConverter代码解决了这个问题。该联盟的想法很有趣。我会测试它并张贴我的结果。

I guess I should have mentioned I was looking for a "safe" implementation... Either way, the BitConverter code solves the problem. The union idea is interesting. I'll test it and post my results.

编辑:
正如预期的那样,不安全的方法是最快的,其次是使用函数内工会( ),其次是BitConverter。这些函数被执行的千万次,我用System.Diagnostics.Stopwatch类时机。 ,计算的结果显示在括号

As expected, the unsafe method is the quickest, followed by using a union (inside the function), followed by the BitConverter. The functions were executed 10000000 times, and the I used the System.Diagnostics.Stopwatch class for timing. The results of the calculations are show in brackets.

Input: 79.67
BitConverter Method: 00:00:01.2809018 (0.1120187)
Union Method: 00:00:00.6838758 (0.1120187)
Unsafe Method: 00:00:00.3376401 (0.1120187)

有关完整性,我测试内置Math.Pow方法,而幼稚的方法(1 / SQRT(x)的)。

For completeness, I tested the built-in Math.Pow method, and the "naive" method (1/Sqrt(x)).

Math.Pow(x, -0.5): 00:00:01.7133228 (0.112034710535584)
1 / Math.Sqrt(x): 00:00:00.3757084 (0.1120347)

1 /的Math.sqrt()之间的差别是如此之小,我不认为一个人需要求助于在C#中的不安全快速InvSqrt()方法(或任何其他不安全的方法)。除非一个人的真正的需要挤出从CPU汁最后一位...... 1 /的Math.sqrt()也更加准确。

The difference between 1 / Math.Sqrt() is so small that I don't think one needs to resort to the Unsafe Fast InvSqrt() method in C# (or any other unsafe method). Unless one really needs to squeeze out that last bit of juice from the CPU... 1/Math.Sqrt() is also much more accurate.

推荐答案

您应该能够使用StructLayout和FieldOffset属性假一联盟普通的旧数据,如浮点数和整数。

You should be able to use the StructLayout and FieldOffset attributes to fake a union for plain old data like floats and ints.

[StructLayout(LayoutKind.Explicit, Size=4)]
private struct IntFloat {
    [FieldOffset(0)]
    public float floatValue;

    [FieldOffset(0)]
    public int intValue;

    // redundant assignment to avoid any complaints about uninitialized members
    IntFloat(int x) {
        floatValue = 0;
        intValue = x;
    }

    IntFloat(float x) { 
        intValue = 0;
        floatValue = x;
    }

    public static explicit operator float (IntFloat x) {
        return x.floatValue;
    }

    public static explicit operator int (IntFloat x) { 
        return x.intValue;
    }

    public static explicit operator IntFloat (int i) {
        return new IntFloat(i);
    }
    public static explicit operator IntFloat (float f) { 
        return new IntFloat(f);
    }
}

然后翻译InvSqrt很容易。

Then translating InvSqrt is easy.

这篇关于是否有可能用C#地震的快速InvSqrt()函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆