gpt4 book ai didi

c# - 是否可以在 C# 中编写 Quake 的快速 InvSqrt() 函数?

转载 作者:IT王子 更新时间:2023-10-29 04:11:28 25 4
gpt4 key购买 nike

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

是否有这样的实现:

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# 中?如果存在,请发布代码。

我想我应该提到我正在寻找一个“安全”的实现...无论哪种方式,BitConverter 代码都解决了这个问题。联盟的想法很有趣。我会对其进行测试并发布我的结果。

编辑:正如预期的那样,不安全方法是最快的,其次是使用联合(在函数内部),然后是 BitConverter。这些函数执行了 10000000 次,我使用 System.Diagnostics.Stopwatch 类进行计时。计算结果显示在括号中。

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))。

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# 中的 Unsafe Fast InvSqrt() 方法(或任何其他不安全的方法)。除非有人真的需要从 CPU 中挤出最后一点汁液……1/Math.Sqrt() 也更准确。

最佳答案

您应该能够使用 StructLayout 和 FieldOffset 属性为普通旧数据(如 float 和整数)伪造联合。

[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 就很容易了。

关于c# - 是否可以在 C# 中编写 Quake 的快速 InvSqrt() 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/268853/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com