【问题标题】:Unusual conversion between float and long [duplicate]浮点数和长整数之间的异常转换[重复]
【发布时间】:2015-01-04 17:15:54
【问题描述】:

我发现了一个非常复杂的函数,这是快速平方根平方根的实现。老实说,我不明白这个函数是如何工作的,但是 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;
}

【问题讨论】:

  • @AShelly:就个人而言,我不认为这是重复的。这是一个非常狭隘的问题。

标签: c casting floating-point bit-manipulation


【解决方案1】:

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

有关算法的说明,请参见 Wikipedia:Fast inverse square root

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

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

它也是无效的 C - 它是一个 aliasing violation。该程序的正确版本需要使用memcpy 或可能(这不太清楚它是否正确,但真正的编译器记录了对它的支持)union-based type punning。不过,OP 代码中的版本肯定会被真正的编译器“错误编译”(即以不同于作者意图的方式)。

这意味着代码不仅是特定于架构的,也是特定于编译器的。

【讨论】:

  • 这也是无效的 C - 这是一个别名冲突。该程序的正确版本需要使用memcpy 或可能(这不太清楚它是否正确,但真正的编译器文档支持它)基于union 的类型双关语。 OP 代码中的版本肯定会被真正的编译器“错误编译”(即以不同于作者意图的方式)。
  • @R.. - 谢谢,我已将其添加到答案中(注明出处)。
  • @NPE:我可以在哪里获得有关您所说的更多信息
  • @CooperJames:相同的 32 位模式可以解释为整数和 IEEE 浮点数。代码获取给定的 32 位浮点数的位,并将它们视为 32 位整数的位。然后它对这些位执行整数运算以发挥其魔力。
  • 唯一的字节序假设是浮点和整数字节序匹配。这在实践中总是正确的。
猜你喜欢
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2022-10-09
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
相关资源
最近更新 更多