具有相同参数的函数不会 return 相同的值

Function with the same argument does not return the same value

我通过尝试优化某些东西(更少的变量等)来“玩”fast inverse sqrt 函数。这是最终代码:

float Q_rsqrt(float x) {
    const float x2 = x * 0.5F;
    uint_fast32_t i;
    memcpy(&i, &x, sizeof(float));
    i = 0x5f3759df - ( i >> 1 );
    memcpy(&x, &i, sizeof(float));
    return x * ( 1.5F - ( x2 * x * x ) );
}

首先,了解在我的体系结构中 uint_fast32_t 以 64 位表示而 float 以 32 位表示是很有用的。因此,对不同大小的变量类型进行 memcpy() 可能会令人惊讶。 代码编译后我遇到的问题是,每次使用相同参数调用此函数都会给出相同的 return 值:有时这个值为负,有时为正(但绝对值始终相同)。 memcpy() 的用处是绕过以下代码(完全按预期工作)的警告(取消引用类型双关指针将破坏严格的别名规则):

float Q_rsqrt_test(float x) {
    const float xHalf = x * 0.5F;
    const uint_fast32_t i = 0x5f3759df - ( (* ( uint_fast32_t * ) &x) >> 1 );
    x = * ( float * ) &i;
    return x * ( 1.5F - ( xHalf * x * x ) );
}

对于这段代码,我想说没有类型大小的问题,因为源代码(在上面的 link 中可见)已经使用了 double type,它表示为 64我架构上的位(而不是 32 位上的 float)。

我真的不明白为什么我用第一个函数就可以得到否定的答案...

感谢您的帮助。

正如 Barmar 所说,将 i 初始化为 0 是可行的。我还认为最好避免取消对具有其他大小的类型的引用(例如 *(uint64_t *) &x,其中 x 是浮点数)。使用 uint32_t 取消引用可能更好,然后将结果正确地转换为 64 位变量。