浮动和长期之间的异常转换

时间:2015-01-04 17:15:54

标签: c casting floating-point bit-manipulation

我发现了一个非常复杂的函数,这是快速反平方根的实现。老实说,我不明白这个函数是如何工作的,但longfloat之间的以下转换引起了我的注意:

i  = *(long *) &y; 

我留下完整的代码

inline float Q_rsqrt(float number)
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = *(long *) &y;                      
    i  = 0x5f3759df - (i >> 1);            
    y  = * (float *) &i;
    y  = y * (threehalfs - (x2 * y * y));  

    return y;
}

1 个答案:

答案 0 :(得分:7)

强制转换只是将y的位重新解释为long,以便它可以对它们执行整数运算。

有关算法的解释,请参阅维基百科:Fast inverse square root

该代码利用了在目标平台上sizeof(long) == sizeof(float)的知识。

@R ..还有助于在评论中添加以下内容:

  

它也是无效的C - 它是aliasing violation。该程序的正确版本需要使用memcpy或可能(这不太清楚,它是正确的,但真正的编译器文档支持它)union-based type punning。 OP代码中的版本肯定是"错误编译" (但是,与作者的意图不同的是,通过真正的编译器)。

这意味着代码不仅是特定于体系结构的,而且也是特定于编译器的。