【Beautiful Algorithm】 Fast Inverse Square Root(快速求平方根倒数)
来自Quick ||| Algorithm, Fast Inverse Square Root 1 x \frac{1}{\sqrt{x}} x1
代码
float Q_rsqrt(float number) {
long i;
float x, y;
const float threehalfs = 1.5F; // <1>
x = number * 0.5F; // <2>
y = number;
i = *(long *) &y; // <3>
i = 0x5f3759df - (i >> 1); // <4>
y = *(float *) &i; // <5>
y = y * (threehalfs - (x * y * y)); // 1st iteration <6>
y = y * (threehalfs - (x * y * y)); // 2st iteration, can be removed // <7>
return y;
}
浮点数的表示 - IEEE 754
对于float
, 其浮点数表示如下图所示。
其他方面
分析1
-
<1>
用在<6>
和<7>
处,放到<6>
和<7>
处分析。 -
<3>
将y的内容变为long的形式,如果使用i = (long)y
,只会得到取整后的值,所以需要改变指针的意义,使得某个指向long的地址指向y。<3>
和<5>
是配对的,<3>
把y中的内容复制出来,<5>
把新的内容放到y中。 -
<4>
对于浮点数0:E:M
,其值为
( 1 + M 2 23 ) × 2 E − 127 (1+\frac{M}{2^{23}}) \times2^{E - 127} (1+223M)×2E−127
对值取 l o g 2 log_2 log2,得
l o g 2 ( ( 1 + M 2 23 ) × 2 E − 127 ) = l o g 2 ( 1 + M 2 23 ) + E − 127 = M 2 23 + μ + E − 127 ( d u e t o l o g 2 ( 1 + x ) ≈ x + μ , 0 < x < 1 ) = 1 2 23 ( M + 2 23 × E ) + μ − 127 \begin{aligned} log_2((1+&\frac{M}{2^{23}}) \times2^{E - 127}) \\ &= log_2(1+\frac{M}{2^{23}}) + E - 127 \\ &= \frac{M}{2^{23}} + \mu + E - 127 \space\space(due\space to\space log_2(1+x) \approx x + \mu, 0<x<1) \\ &= \frac{1}{2^{23}}(M+2^{23}\times{E}) + \mu - 127 \end{aligned} log2((1+223M)×2E−127)=log2(1+223M)+E−127=223M+μ+E−127 (due to log2(1+x)≈x+μ,0<x<1)=2231(M+223×E)+μ−127
其中 ( M + 2 23 × E ) (M+2^{23}\times{E}) (M+223×E)就是float的数字表示结果,即 i i i得值。
i = ( M + 2 23 × E ) i = (M+2^{23}\times{E}) i=(M+223×E)
令 Γ = 1 x \Gamma=\frac{1}{\sqrt{x}} Γ=x1,其中 x = ( 1 + M 2 23 ) × 2 E − 127 x=(1+\frac{M}{2^{23}}) \times2^{E - 127} x=(1+223M)×2E−127,则
log 2 ( Γ ) = log 2 1 x f o r l e f t : log 2 1 x = log 2 ( x − 1 2 ) = − 1 2 log 2 ( x ) = − 1 2 ( 1 2 23 ( M x + 2 23 × E x ) + μ − 127 ) f o r r i g h t : log 2 ( Γ ) = 1 2 23 ( M Γ + 2 23 × E Γ ) + μ − 127 c o m b i n e l e f t a n d r i g h t : ( M Γ + 2 23 × E Γ ) = 2 3 2 23 ( 127 − μ ) − 1 2 ( M x + 2 23 × E x ) ⇒ ( M Γ + 2 23 × E Γ ) = 0 × 5 f 3759 d f − ( i > > 1 ) \begin{aligned} \log_2(\Gamma) &= \log_2{\frac{1}{\sqrt{x}}} \\ for \space left : \quad \log_2{\frac{1}{\sqrt{x}}} &= \log_2(x^{-\frac{1}{2}}) \\ &=-\frac{1}{2}\log_2(x) \\ &= -\frac{1}{2}( \frac{1}{2^{23}}(M_x+2^{23}\times{E_x}) + \mu - 127) \\ for \space right: \quad \log_2(\Gamma) &= \frac{1}{2^{23}}(M_{\Gamma}+2^{23}\times{E_{\Gamma}}) + \mu - 127 \\ combine \space left\space and\space right: \quad \quad \quad\quad \space\\ (M_{\Gamma}+2^{23}\times{E_{\Gamma}}) &= \frac{2}{3}2^{23}(127-\mu)-\frac{1}{2}(M_x+2^{23}\times{E_x}) \\ \Rightarrow \quad \quad \quad \quad\quad \quad\quad\quad \\ (M_{\Gamma}+2^{23}\times{E_{\Gamma}}) &= 0\times5f3759df - (i >> 1) \end{aligned} log2(Γ)for left:log2x1for right:log2(Γ)combine left and right: (MΓ+223×EΓ)⇒(MΓ+223×EΓ)=log2x1=log2(x−21)=−21log2(x)=−21(2231(Mx+223×Ex)+μ−127)=2231(MΓ+223×EΓ)+μ−127=32223(127−μ)−21(Mx+223×Ex)=0×5f3759df−(i>>1)
( M Γ + 2 23 × E Γ ) (M_{\Gamma}+2^{23}\times{E_{\Gamma}}) (MΓ+223×EΓ)是 Γ = 1 x \Gamma=\frac{1}{\sqrt{x}} Γ=x1的整数值表示,步骤<5>
则将其转化为浮点数。 -
<6>
所示的是迭代公式,不断逼近目标值
Newton Method 用于解决 f ( x ) = 0 f(x)=0 f(x)=0的零点查找问题。迭代公式为:
x n e w = x − f ( x ) f ′ ( x ) x_{new} = x - \frac{f(x)}{f^{'}(x)} xnew=x−f′(x)f(x)
对于本题, x x x为输入的number,我们需要求的值是 1 ( x ) = y \frac{1}{\sqrt(x)} = y (x)1=y,故而目标函数是:
f ( y ) = 1 y 2 − x f(y) = \frac{1}{y^2} - x f(y)=y21−x
故而迭代公式是
y n e w = y ( 3 2 − 1 2 x y 2 ) y_{new} = y(\frac{3}{2} - \frac{1}{2}xy^2) ynew=y(23−21xy2)
评估本函数的误差
TODO
https://www.youtube.com/watch?v=p8u_k2LIZyo ↩︎