Q_rsqrt()
float Q_rsqrt( float
number
)
{
long
i
;
float
x2
,
y
;
const float
threehalfs
=
1.5
F
;
x2
=
number
*
0.5
F
;
y
=
number
;
i
= *
(
long
*
)
&
y
;
// evil floating point bit level hacking
i
=
0x
5f3759df
-
(
i
>>
1
)
;
// what the fuck?
y
= *
(
float
*
)
&
i
;
y
=
y
*
(
threehalfs
-
(
x2
*
y
*
y
) )
;
// 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return
y
;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
id Software - GPLv2
Gary Tarolli
3dfx Interactive
Brian Hook
3dfx Interactive
id Software
John Carmack
id Software
William Kahan
unpublished paper 1986
"The Father of Floating Point"
Cleve Moler
Ardent Computer
MatLab
1999
Greg Walsh
Ardent Computer
long
float
a history
The story of
void VectorNormalizeFast( vec3_t
v
)
{
float
ilength
;
ilength
=
Q_rsqrt( DotProduct(
v
,
v
) )
;
v[0]
*=
ilength
;
v[1]
*=
ilength
;
v[2]
*=
ilength
;
}
long
00000000 00000000 00000000 00000000
0
00000000 00000000 00000000 00000001
1
00000000 00000000 00000000 00000010
2
00000000 00000000 00000000 00000011
3
...
01111111 11111111 11111111 11111111
2
147
483
647
float
(IEEE 754 single precision)
0
00000000
0000000 00000000 00000000
float
(sign)
0
00000000
0000000 00000000 00000000
float
(exponent)
0
0000000 00000000 00000000
±
0.0 x
2
float
(mantissa)
0.000000 00000000 00000000
0
1 sign bit
00000010
0
00000000
0
00000000
0000000 00000000 00000000
Links
8 exponent bits
[0,255]
Scientific notation
float
(IEEE 754 exemples)
1
00000000
0000000 00000000 00000000
-
0
0
-0.0000000
0
01111111
0000000 00000000 00000000
+
127
0
+1.0000000
0
10000000
1001001 00001111 11011011
+
128
4788187
+3.1415927
0
01101011
0000110 00110111 10111101
+
103
5685141
+0.0000001
0 → +
1 → -
±
0.0 x
2
0
±
0.0 x
2
0
00000000 00000000 00000000 00000000
≠ 0
float
(mantissa)
0000000 00000000 00000000
0
00000000
.
±
0.0 x
2
0
µ
µ
µ
±
1
.0 x
2
0
y
y
y
y
i
i
i
0x
5f3759df
// what the fuck?
i
=
0x
5f3759df
-
(
i
>>
1
)
;
y
y
y
y
y
y
y
i
y
8 shifted exponent bits
[0,255] - 127
⇒
[-127,128]
2-127
2
8 shifted exponent bits
[0,255] - 127
⇒
[-127,128]
00000010
10000001
2-127
2 = 2
2-127
-125
2 = 2
129-127
2
[0,2 -1] ≠ [0,1[
23
00000000
....... ........ ........
0000000 00000000 00000000
0000000 00000000 00000000
// evil floating point bit level hacking
i
= *
(
long
*
)
&
y
;
y
&
y
float
*
float
00000000 00000000 00000000 00000000
(
long
*
)
&
y
long
193549ff
i
00000000 00000000 00000000 00000000
long
// 1st iteration - Newton-Raphson's method
y
=
y
*
(
threehalfs
-
(
x2
*
y
*
y
) )
;
approximation error
approximation error %
Newton-Raphson's
method
pow(number, -0.5f)
1 / sqrt(number)
Q_rsqrt(number)
_mm_rsqrt_ss(number)
95%
50%
mediane
Inkscape
Sozi
sprites
© id Software
Jérôme Labidurie - 2024
Merci
Questions ?
Lighting, Shading & Reflection
calculations
Surface normals
field of unit vectors normal to a surface
Quake ]|[ Fast Inverse Square Root
Q_rsqrt(number)
number
⇔
Sources
History - Rys Sommefeldt (Beyond3D )
https://www.beyond3d.com/content/articles/8/
https://www.beyond3d.com/content/articles/15/
The Maths behind the rsqrt function - Charles McEniry
http://www.daxia.com/bibis/upload/406Fast_Inverse_Square_Root.pdf
Wikipedia
https://en.wikipedia.org/wiki/Fast_inverse_square_root
Fast Inverse Square Root — A Quake III Algorithm - Nemean
https://www.youtube.com/watch?v=p8u_k2LIZyo
The Truth about the Fast rsqrt on the N64 - Kaze Emanuar
https://www.youtube.com/watch?v=tmb6bLbxd08
Q_rsqrt()
Jérôme Labidurie
CC:BY-SA
english
1
Intro
Why ?
Vectors
History
line 1
line 3
long
line 4
line 5
float sign
float exponent
float mantissa
float exemples
line 9
evil1
line 10
float bits
log 1+x
WTF
line 11
line 12
newton
line 13
approx
line 15
benchmark
This is the end