《雷神之锤III》平方根倒数算法 学习笔记

news/2024/11/8 20:47:09/

今天刷到个算法视频,觉得很有意思,所以打算把它记录下来。

平方根倒数算法

  • 源代码
  • 二进制浮点数运算
  • 对数技巧
  • 平方根倒数
  • 牛顿迭代

源代码

float Q_rsqrt(float number)
{long i;float x2, y;const float threehalfs = 1.5F;x2 = number * 0.5F;y = number;i = *(long *) &y;						// evil float point bit hacki = 0x5f3759df - (i >> 1);				// what the fuck?y = * (float *) &i;y = y * (threehalfs - (x2 * y * y)); 	// 1st iteration// y = y * (threehalfs - (x2 * y * y)); // 2nd iteration, can be removedreturn y;
}

二进制浮点数运算

  • 参考标准 IEEE 754

  • 计算机中 小数(浮点数)表示 由三部分二进制组成 : S 符号位 sign, E 指数偏移值 exponent bias, M 尾数位 Mantissa。以32为 浮点数 float 为例:

    • 1位 符号位,8位指数位,23位有效数字位32位浮点float
    • E ∈ ( − 127 , 128 ] , M ∈ [ 0 , 2 23 − 1 ] E \in (-127, 128], \ M\in[0, 2^{23}-1] E(127,128], M[0,2231]
    • 其表示值 Value V 32 = S × 2 E − 127 × ( 1 + 1 2 23 M ) \begin{aligned}V_{32} &= S \times 2^{E - 127} \times (1 + \frac{1}{2^{23}}M) \end{aligned} V32=S×2E127×(1+2231M)
  • 拓展延伸

    • 双精度 浮点数 double64位浮点double

      V 64 = S × 2 E − 1023 × ( 1 + 1 2 51 M ) \begin{aligned}V_{64} &= S \times 2^{E - 1023} \times (1 + \frac{1}{2^{51}}M) \end{aligned} V64=S×2E1023×(1+2511M)

    • 尾数位(Mantissa),它的取值范围为 1 ~ 2 ,或者为 0~1。它也被称为分数值(fraction)、系数位(Coefficient),有效数字位(Significand)。

    • 特殊数值:

      • 0 : 0 00000000 0000000000000000000000
        0 : 1 00000000 0000000000000000000000
      • NaN:
        • 指数位所有位都是1, 小数位只要不全为0,就表示非数值
        • 例:0 11111111 11111111111100000010000
      • Infinity:
        • 符号位 0表示正无穷大,1表示负无穷大;
        • 指数位 所有位都是1;
        • 小数位所有位都是0。
        • 例:0 11111111 00000000000000000000000
类别正负号实际指数有偏移指数指数域尾数域数值
0-12700000 0000000 0000 0000 0000 0000 00000.0
负零1-12700000 0000000 0000 0000 0000 0000 0000−0.0
1001270111 1111000 0000 0000 0000 0000 00001.0
-1101270111 1111000 0000 0000 0000 0000 0000−1.0
最小的非规约数*-12700000 0000000 0000 0000 0000 0000 0001±2× 2= ±2≈ ±1.4×10
中间大小的非规约数*-12700000 0000100 0000 0000 0000 0000 0000±2× 2= ±2≈ ±5.88×10
最大的非规约数*-12700000 0000111 1111 1111 1111 1111 1111±(1−2) × 2≈ ±1.18×10
最小的规约数*-12610000 0001000 0000 0000 0000 0000 0000±2≈ ±1.18×10
最大的规约数*1272541111 1110111 1111 1111 1111 1111 1111±(2−2) × 2≈ ±3.4×10
正无穷01282551111 1111000 0000 0000 0000 0000 0000+∞
负无穷11282551111 1111000 0000 0000 0000 0000 0000−∞
NaN*1282551111 1111non zeroNaN

对数技巧

  • 因为 平方根底数 为 正 S = + 1 S = +1 S=+1
  • log ⁡ 2 ( V 32 ) = log ⁡ 2 ( 2 E − 127 × ( 1 + 1 2 23 M ) ) = E − 127 + log ⁡ 2 ( 1 + 1 2 23 M ) ≈ E − 127 + 1 2 23 M + μ , log ⁡ 2 ( 1 + x ) ≈ x + μ ≈ 1 2 23 ( M + 2 23 × E ) + μ − 127 \begin{aligned} \log_2 ( V_{32}) &= \log_2 \Big( 2^{E - 127} \times (1 + \frac{1}{2^{23}}M)\Big) \\ &= E - 127 + \log_2 (1 + \frac{1}{2^{23}}M) \\ &\approx E - 127 + \frac{1}{2^{23}}M + \mu \ , \ \log_2 (1+x) \approx x + \mu \\ & \approx \frac{1}{2^{23}}(M + 2^{23}\times E) + \mu - 127 \end{aligned} log2(V32)=log2(2E127×(1+2231M))=E127+log2(1+2231M)E127+2231M+μ , log2(1+x)x+μ2231(M+223×E)+μ127
  • M + 2 23 × E = M + ( E < < 23 ) = M + 2^{23} \times E = M + (E << 23) = M+223×E=M+(E<<23)= (binary) V 32 V_{32} V32

平方根倒数

  • 1 x = x − 1 2 \frac{1}{\sqrt{x}} = x ^{-\frac{1}{2}} x 1=x21
  • log ⁡ 2 ( 1 y ) = − 1 2 log ⁡ 2 ( y ) = − ( log ⁡ 2 ( y ) > > 1 ) \log_2(\frac{1}{\sqrt{y}}) = -\frac{1}{2} \log_2(y) = -(\log_2(y)>>1) log2(y 1)=21log2(y)=(log2(y)>>1)
  • Let log ⁡ ( Γ ) = − 1 2 log ⁡ ( y ) \log(\Gamma) = -\frac{1}{2} \log(y) log(Γ)=21log(y)
  • 1 2 23 ( M Γ + 2 23 × E Γ ) + μ − 127 = − 1 2 ( 1 2 23 ( M y + 2 23 × E y ) + μ − 127 ) ( M Γ + 2 23 × E Γ ) = 3 2 2 23 ( 127 − μ ) − 1 2 ( M y + 2 23 × E y ) = 0x5f3759df − ( y > > 1 ) \begin{aligned} \frac{1}{2^{23}}(M_\Gamma + 2^{23}\times E_\Gamma) + \mu - 127 &= -\frac{1}{2} (\frac{1}{2^{23}}(M_y + 2^{23}\times E_y) + \mu - 127) \\ (M_\Gamma + 2^{23}\times E_\Gamma) &= \frac{3}{2} 2^{23}(127 - \mu) - \frac{1}{2} (M_y + 2^{23}\times E_y) \\ &= \text{0x5f3759df} - (y >> 1) \end{aligned} 2231(MΓ+223×EΓ)+μ127(MΓ+223×EΓ)=21(2231(My+223×Ey)+μ127)=23223(127μ)21(My+223×Ey)=0x5f3759df(y>>1)
  • 再把二进制整数 转换成浮点数,结果为近似值,需要用牛顿迭代减少误差。

牛顿迭代

y = 1 x → x = 1 y 2 y = \frac{1}{\sqrt{x}} \to x = \frac{1}{y^2} y=x 1x=y21
f ( y ) = 1 y 2 − x f(y)=\frac{1}{y^{2}}-x f(y)=y21x
y new  = y − f ( y ) f ′ ( y ) = y − 1 y 2 − x − 2 y 3 = 3 2 y − 1 2 x y 3 y_{\text {new }}=y-\frac{f(y)}{f^{\prime}(y)}=y-\frac{\frac{1}{y^{2}}-x}{-\frac{2}{y^{3}}}=\frac{3}{2}y-\frac{1}{2} x y^{3} ynew =yf(y)f(y)=yy32y21x=23y21xy3


http://www.ppmy.cn/news/141629.html

相关文章

《雷神之锤 Ⅲ》平方根倒数速算法魔术数字的另一种求法(2)

上图代码是出自雷神之锤3计算一个正实数的算术平方根的倒数的算法&#xff0c;一般我们去计算一个数的平方根采用最好的方法是牛顿迭代法 不会牛顿迭代法&#xff0c;可以去看下这位大哥的帖子 www.cnblogs.com/houkai/p/3332520.html 比如我们要求 x 的平方根倒数&#xff…

linux运行雷神之锤,RTX改造版《雷神之锤II》现已开放下载

原标题&#xff1a;RTX改造版《雷神之锤II》现已开放下载 早些时候&#xff0c;英伟达宣布了要携手贝塞斯达&#xff0c;为 1997 年推出的经典游戏《雷神之锤 II》提供 RTX 光线追踪支持的消息。原版用户可以通过补丁来获得全新的体验&#xff0c;如果找不到安装光盘&#xff0…

牛顿迭代法——雷神之锤

牛顿迭代法——雷神之锤 震惊&#xff01;&#xff01;&#xff01; https://blog.csdn.net/wangxiaojun911/article/details/18203333

GPT现状终于有人讲清楚了!OpenAI大牛最新演讲爆火,还得是马斯克钦点的天才

量子位 | 公众号 QbitAI 继Windows Copilot发布后&#xff0c;微软Build大会热度又被一场演讲引爆。 前特斯拉AI总监Andrej Karpathy在演讲中认为思维树&#xff08;tree of thoughts&#xff09;与AlphaGo的蒙特卡洛树搜索&#xff08;MCTS&#xff09;有异曲同工之妙&#…

C++开源游戏推荐,雷神之锤1/2/3

声明&#xff1a;项目非本人原创&#xff0c;仅仅分享链接&#xff01; John Carmack是游戏程序员。 https://github.com/id-Software/Quake https://github.com/id-Software/Quake-2 https://github.com/id-Software/Quake-III-Arena 《雷神之锤2》(Quake2)GitHub开源项目…

雷神之锤

注意&#xff1a;本文中包含程序代码&#xff0c;建议在手机上使用横屏阅读以获得更好的体验&#xff0c;在电脑上阅读可获得最佳体验 奎特尔星球上有一件绝世神兵&#xff0c;就像是一把雷神之锤&#xff0c;在它的号令之下指挥着节点、组件和触摸事件&#xff0c;从而大量减少…

雷神之锤暴力压缩算法

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace 雷神之锤暴力压缩算法 {public partial class Form1 : Form{public …

简单易学!使用 Node.js 编写爬虫,跟着教程一步步实现!

爬虫是一种可以自动从网页上获取数据的程序&#xff0c;它可以帮助我们收集和分析各种有用的信息。在这篇文章中&#xff0c;我将向你展示如何用 node.js 来编写一个简单的爬虫&#xff0c;只需几步就可以实现。 1、安装 node.js 和 npm node.js 是一个基于 Chrome V8 引擎的…