求*方根的倒数
给一个数,求次数的*方根倒数,保留小数点后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);
中:
i >> 1
:将浮点数表示的整数位右移1位,相当于将指数部分减少一半(即*方根的概念)。0x5f3759df
:这个魔数经过多次实验优化,能够生成非常接**方根倒数的初始估计值。- 最后的结果经过牛顿迭代法进一步优化,使其精度更高。
魔数的来源
虽然我们无法简单推导出这个魔数的来源,但它背后依赖的是浮点数表示法(IEEE 754标准)中指数和尾数的位级别操作。这个魔数是在经过大量实验和经验基础上确定的,经过位操作能够生成接**方根倒数的估计值,从而大幅减少需要计算的浮点运算量。
总结
- 魔数是经过特定经验或复杂推导得到的特殊数值,在特定算法中用于提高效率。
- 在 快速*方根倒数算法 中,
0x5f3759df
这个魔数是为了对浮点数的二进制表
示进行位操作,快速接**方根倒数的初始值。 - 它结合了位操作和数值逼*技巧,使得该算法在3D渲染等场景中非常高效。
7、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、7;