Skip to content

Commit 415589a

Browse files
committed
Added recipe for fast inverse square root.
1 parent bab6390 commit 415589a

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

chapters/math/fast-inv-square.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
layout: recipe
3+
title: Fast Inverse Square Root
4+
chapter: Math
5+
---
6+
## Problem
7+
8+
You would like to calculate a the inverse square root[5] of a number quickly.
9+
10+
## Solution
11+
Appearing in the Quake III Arena source code[1], this strange algorithm uses
12+
integer operations along with a 'magic number' to calculate floating point
13+
approximation values of inverse square roots.
14+
15+
In this CoffeeScript variant I supply the original classic, and newer optimal
16+
32 bit magic numbers found by Chris Lomont[2]. Also supplied is the 64-bit
17+
sized magic number.
18+
19+
Another feature included is the ability to alter the level of precision.
20+
This is done by controling the number of iterations for performing Newton's
21+
method[3].
22+
23+
Depending on the machine and level of percision this algorithm may still
24+
provide performance increases over the classic.
25+
26+
To run this, compile the script with coffee:
27+
coffee -c <this script>.coffee
28+
29+
Then copy & paste the compiled js code in to the JavaSript console of your
30+
browser.
31+
32+
Note: You will need a browser which supports typed-arrays[4].
33+
34+
References:
35+
* [1] [ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip](ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip)
36+
* [2] [http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf](http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf)
37+
* [3] [http://en.wikipedia.org/wiki/Newton%27s_method](http://en.wikipedia.org/wiki/Newton%27s_method)
38+
* [4] [https://developer.mozilla.org/en/JavaScript_typed_arrays](https://developer.mozilla.org/en/JavaScript_typed_arrays)
39+
* [5] [http://en.wikipedia.org/wiki/Fast_inverse_square_root](http://en.wikipedia.org/wiki/Fast_inverse_square_root)
40+
41+
This code is in gist form here:
42+
[https://gist.github.com/1036533](https://gist.github.com/1036533)
43+
44+
{% highlight coffeescript %}
45+
###
46+
47+
Author: Jason Giedymin <jasong _a_t_ apache -dot- org>
48+
http://www.jasongiedymin.com
49+
https://github.com/JasonGiedymin
50+
51+
Appearing in the Quake III Arena source code[1], this strange algorithm uses
52+
integer operations along with a 'magic number' to calculate floating point
53+
approximation values of inverse square roots.
54+
55+
In this CoffeeScript variant I supply the original classic, and newer optimal
56+
32 bit magic numbers found by Chris Lomont[2]. Also supplied is the 64-bit
57+
sized magic number.
58+
59+
Another feature included is the ability to alter the level of precision.
60+
This is done by controling the number of iterations for performing Newton's
61+
method[3].
62+
63+
Depending on the machine and level of percision this algorithm may still
64+
provide performance increases over the classic.
65+
66+
To run this, compile the script with coffee:
67+
coffee -c <this script>.coffee
68+
69+
Then copy & paste the compiled js code in to the JavaSript console of your
70+
browser.
71+
72+
Note: You will need a browser which supports typed-arrays[4].
73+
74+
References:
75+
[1] ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip
76+
[2] http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
77+
[3] http://en.wikipedia.org/wiki/Newton%27s_method
78+
[4] https://developer.mozilla.org/en/JavaScript_typed_arrays
79+
80+
###
81+
82+
approx_const_quake_32 = 0x5f3759df # See [1]
83+
approx_const_32 = 0x5f375a86 # See [2]
84+
approx_const_64 = 0x5fe6eb50c7aa19f9 # See [2]
85+
86+
fastInvSqrt_typed = (n, precision=1) ->
87+
# Using typed arrays. Right now only works in browsers.
88+
# Node.JS version coming soon.
89+
90+
y = new Float32Array(1)
91+
i = new Int32Array(y.buffer)
92+
93+
y[0] = n
94+
i[0] = 0x5f375a86 - (i[0] >> 1)
95+
96+
for iter in [1...precision]
97+
y[0] = y[0] * (1.5 - ((n * 0.5) * y[0] * y[0]))
98+
99+
return y[0]
100+
101+
### Sample single runs ###
102+
testSingle = () ->
103+
example_n = 10
104+
105+
console.log("Fast InvSqrt of 10, precision 1: #{fastInvSqrt_typed(example_n)}")
106+
console.log("Fast InvSqrt of 10, precision 5: #{fastInvSqrt_typed(example_n, 5)}")
107+
console.log("Fast InvSqrt of 10, precision 10: #{fastInvSqrt_typed(example_n, 10)}")
108+
console.log("Fast InvSqrt of 10, precision 20: #{fastInvSqrt_typed(example_n, 20)}")
109+
console.log("Classic of 10: #{1.0 / Math.sqrt(example_n)}")
110+
111+
testSingle()
112+
113+
{% endhighlight %}
114+
115+
## Discussion
116+
117+
Questions?

0 commit comments

Comments
 (0)