求*方根的倒数

给一个数,求次数的*方根倒数,保留小数点后6位。


#include <stdio.h>

float Q_rsqrt(float number) {
    long i;                 // 用来存储位操作结果
    float x2, y;
    const float threehalfs = 1.5f;  // 常数1.5

    x2 = number * 0.5f;     // 计算 number 的一半
    y = number;             // 将输入值赋给 y

    // 位级别的操作,把 float 转换为整数进行操作
    i = *(long*)&y;         // 将 float 转换为 long 型(使用同样的位表示)
    i = 0x5f3759df - (i >> 1); // 魔数操作,快速*似*方根倒数
    y = *(float*)&i;        // 将结果转换回 float

    // 进行一次牛顿迭代法的计算,提升精度
    y = y * (threehalfs - (x2 * y * y)); 

    return y;               // 返回*方根的倒数
}


int main() {
    float number = 16.0f;
    float result = Q_rsqrt(number);
    printf("*方根倒数为: %.6f\n", result);
    return 0;
}

i = 0x5f3759df - (i >> 1); // 魔数操作,快速*似*方根倒数 什么是魔数?

魔数(Magic Number)是指在某些计算或算法中使用的一个固定的数值,它通常是在某种特定情况下,经过经验或复杂的推导得出的,能够显著提高某种计算的效率或达到某种效果。在代码中,这些数值看似神秘,难以从代码中直接推断它们的来源,因此被称为“魔数”。

魔数在快速*方根倒数算法中的作用

在你提到的 0x5f3759df 这一行代码中,魔数 0x5f3759df 是用来进行快速*方根倒数计算的关键。这一数值是通过经验、优化、甚至逆向工程得到的。它的作用是通过位级操作快速逼**方根倒数的初始值,从而减少后续计算的复杂性。
该算法是经典的 Quake III 游戏中用来快速计算 3D 场景中的光照和物理效果的,其中需要大量的*方根运算。为了提高计算速度,开发者 John Carmack 设计了这一算法,使用位操作和“魔数”进行*似计算。

该魔数的作用机理

*方根倒数的计算通常比较复杂,需要使用浮点运算。而通过位操作,可以直接对浮点数的二进制表示进行修改,得到一个非常接*实际结果的*似值。0x5f3759df 是针对IEEE 754单精度浮点数格式(32位)的魔数,作用是在浮点数的位表示上进行调整,利用计算机内存中的二进制结构,使得算法可以以极快的速度估算*方根倒数。

如何工作的?

在算法的关键步骤中,i = 0x5f3759df - (i >> 1); 中:

  1. i >> 1:将浮点数表示的整数位右移1位,相当于将指数部分减少一半(即*方根的概念)。
  2. 0x5f3759df:这个魔数经过多次实验优化,能够生成非常接**方根倒数的初始估计值。
  3. 最后的结果经过牛顿迭代法进一步优化,使其精度更高。

魔数的来源

虽然我们无法简单推导出这个魔数的来源,但它背后依赖的是浮点数表示法(IEEE 754标准)中指数和尾数的位级别操作。这个魔数是在经过大量实验和经验基础上确定的,经过位操作能够生成接**方根倒数的估计值,从而大幅减少需要计算的浮点运算量。

总结

  • 魔数是经过特定经验或复杂推导得到的特殊数值,在特定算法中用于提高效率。
  • 快速*方根倒数算法 中,0x5f3759df 这个魔数是为了对浮点数的二进制表
    示进行位操作,快速接**方根倒数的初始值。
  • 它结合了位操作和数值逼*技巧,使得该算法在3D渲染等场景中非常高效。

7、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、7;

posted @ 2024-10-15 23:52  专心Coding的程侠  阅读(7)  评论(0编辑  收藏  举报