E
:
3
+
127
E:3+127
E:3+127
M
:
00001
⋯
(
补
18
个
0
填
满
23
位
)
M:00001\cdots(补18个0填满23位)
M:00001⋯(补18个0填满23位) 我们可以得出E e和M m的关系式
E
=
e
+
127
E=e+127
E=e+127
M
=
2
23
∗
m
M={2}^{23}*m
M=223∗m 三.数学推导
y
=
1
x
y= \frac{1}{\sqrt x} \quad
y=x1 取对数:
①
log
2
y
=
−
0.5
∗
log
2
①\log_2 y=-0.5* \log_2
①log2y=−0.5∗log2 将y和x分别用二进制科学计数法表示:
②
y
=
(
1
+
m
y
)
∗
2
e
y
②y=(1+m_y)*{2}^{e_y}
②y=(1+my)∗2ey
③
x
=
(
1
+
m
x
)
∗
2
e
x
③x=(1+m_x)*{2}^{e_x}
③x=(1+mx)∗2ex
联合上述三个式子化简:
l
o
g
2
(
1
+
m
y
)
+
e
y
=
−
0.5
∗
(
l
o
g
2
(
1
+
m
x
)
+
e
x
)
log_2 (1+m_y)+e_y=-0.5*(log_2(1+m_x)+e_x)
log2(1+my)+ey=−0.5∗(log2(1+mx)+ex) 通过一次线性近似:
m
y
+
b
+
e
y
=
−
0.5
∗
(
m
x
+
b
+
e
x
)
m_y+b+e_y=-0.5*(m_x+b+e_x)
my+b+ey=−0.5∗(mx+b+ex)
m
y
=
M
y
2
23
m_y= \frac{M_y}{{2}^{23}} \quad
my=223My
m
x
=
M
x
2
23
m_x= \frac{M_x}{{2}^{23}} \quad
mx=223Mx
E
y
=
e
y
+
127
E_y=e_y+127
Ey=ey+127
E
x
=
e
x
+
127
E_x=e_x+127
Ex=ex+127 上述五个式化简:
M
y
+
2
23
∗
E
y
=
1.5
∗
2
23
∗
(
127
−
b
)
−
0.5
∗
(
M
x
+
2
23
∗
E
x
)
M_y+{2}^{23}*E_y=1.5*{2}^{23}*(127-b)-0.5*(M_x+{2}^{23}*E_x)
My+223∗Ey=1.5∗223∗(127−b)−0.5∗(Mx+223∗Ex) 令
I
y
=
M
y
+
2
23
∗
E
y
I_y=M_y+{2}^{23}*E_y
Iy=My+223∗Ey
I
x
=
M
x
+
2
23
∗
E
x
I_x=M_x+{2}^{23}*E_x
Ix=Mx+223∗Ex 对于
1.5
∗
2
23
∗
(
127
−
b
)
1.5*{2}^{23}*(127-b)
1.5∗223∗(127−b)我们令其为K,可以知道通过调节b的大小就可以改变K的值
前辈们给出了当
b
=
0.0450465
b=0.0450465
b=0.0450465时有K=
K
=
0
x
5
f
3759
d
f
K=0x5f3759df
K=0x5f3759df 这刚好对应代码中:
i=0x5f3759df-(i>>1);
通过一系列不怎么复杂的数学推导我们究竟得到了什么? 我们知道了一个输出结果的整形和输入整形之间的关系,即:
I
y
=
K
−
0.5
∗
I
x
I_y=K-0.5*I_x
Iy=K−0.5∗Ix 四.代码解释 ①
long i;float x2,y;constfloat threehalfs =1.5F;
x2= number *0.5F;
y= number;
i=*(long*)&y;
这句的理解在第三大部分可以轻松找到。 简单来说我们通过放缩系数和平移操作代替了除法和开方的过程,这大大提高了代码运行效率。 ③
y =*(float*)&i;
和①类似我们再次通过这种操作将二进制位转换成浮点数。
通过上述三步我们得到了一个近似值。因此我们还需要进行牛顿迭代法继续使结果精确。 ④
y=y *(threehalfs -(x2*y*y));
下面进行牛顿迭代法的数学推导:
y
=
1
x
y= \frac{1}{\sqrt x}
y=x1
f
(
y
)
=
1
y
2
−
x
f(y)=\frac{1}{y^2}-x
f(y)=y21−x
y
n
+
1
=
y
n
−
1
y
n
2
−
x
−
2
y
n
3
=
y
n
∗
(
3
2
−
1
2
∗
x
∗
y
n
2
)
y_{n+1}=y_n-\frac{\frac{1}{y_n^2}-x}{\frac{-2}{y_n^3}}=y_n*(\frac{3}{2}-\frac{1}{2}*x*y_n^2)
yn+1=yn−yn3−2yn21−x=yn∗(23−21∗x∗yn2)