Fast Inverse Sqrt()[来自Quake3源代码]适用于Visual Studio,但不适用于Eclips



我在C程序中有以下函数:

float invsqrt_32(float number) {
long int i; /* expected to be 32 bits */
float x2;
float y;

x2 = number * 0.5F;

i = * ( long int * ) &number;                       
i = 0x5f375a86 - ( i >> 1 );               
y = * ( float * ) &i;

y *= ( 1.5F - ( x2 * y * y ) );   
y *= ( 1.5F - ( x2 * y * y ) );   
return (y * ( 1.5F - ( x2 * y * y ) )); }

它是从这里改编的,并根据我们的需求和进一步的研究进行了一些改进/改编。

使用输入

number = 4.52949917e-06

在幻数和位屏蔽操作之后,在Windows 10上的Visual Studio 2017(默认编译器)上,我得到

i = 1139498105

但在Ubuntu 18.04(Linux gcc)上的Eclipse 2021.09中,我得到了

i = -3074621553247560583

我不明白这是怎么发生的
我应该怎么做才能找到差异的来源?

此问题是由在64位Linux上使用64位长的long int类型引起的,而在64位Windows上使用32位长的类型。类型应与IEEE 754float的长度相同,后者为32位长。

正确的解决方案应该使用stdint.h中的int32_t,但从评论中可以看出,平台配置不正确,int32_t实际上是64位长。

解决方法是使用int,而不是在Linux和Windows平台上都是32位长的long int

float invsqrt_32(float number) {
int i; /* expected to be 32 bits */
float x2;
float y;

x2 = number * 0.5F;

i = * (int * ) &number;                       
i = 0x5f375a86 - ( i >> 1 );               
y = * ( float * ) &i;

y *= ( 1.5F - ( x2 * y * y ) );   
y *= ( 1.5F - ( x2 * y * y ) );   
return (y * ( 1.5F - ( x2 * y * y ) )); }

注意,该解决方案在技术上违反了";严格混叠规则";其禁止经由指向CCD_ 9的指针来访问类型为CCD_。为了完全合规,重新解释应该通过其他方式进行,比如工会投票。

union {
float f;
int i;
} u = { number };
i = u.i;

相关内容

最新更新