\section{The Fast Inverse Square Root} The following code is present in \textit{Quake III Arena} (1999): \lstset{ breaklines=false, numbersep=5pt, xrightmargin=0in } \begin{lstlisting}[language=C] float Q_rsqrt( float number ) { long i = * ( long * ) &number; i = 0x5f3759df - ( i >> 1 ); return * ( float * ) &i; } \end{lstlisting} This code defines a function \texttt{Q\_rsqrt} that consumes a float named \texttt{number} and approximates its inverse square root (in other words, \texttt{Q\_rsqrt} computes $1/\sqrt{\texttt{number}}$). \vspace{2mm} If we rewrite this using notation we're familiar with, we get the following: \begin{equation*} \texttt{Q\_sqrt}(n_f) = 6240089 - (n_i \div 2) \approx \frac{1}{\sqrt{n_f}} \end{equation*} \note{ \texttt{0x5f3759df} is $6240089$ in hexadecimal. \par It is a magic number hard-coded into \texttt{Q\_sqrt}. } \vspace{2mm} Our goal in this section is to understand why this works: \par \begin{itemize} \item How does Quake approximate $\frac{1}{\sqrt{x}}$ by simply subtracting and dividing by two? \item What's special about $6240089$? \end{itemize} \problem{} Using basic log rules, rewrite $\log_2(1 / \sqrt{x})$ in terms of $\log_2(x)$. \begin{solution} \begin{equation*} \log_2(1 / \sqrt{x}) = \frac{-1}{2}\log_2(x) \end{equation*} \end{solution} \vfill \pagebreak \generic{Setup:} We are now ready to show that $\texttt{Q\_sqrt} \approx \frac{1}{\sqrt{n_f}}$. \par For convenience, let's call the bit string of the inverse square root $r$. \par In other words, \begin{equation*} r_f := \frac{1}{\sqrt{n_f}} \end{equation*} This is the value we want to approximate. \problem{} Find an approximation for $\log_2(r_f)$ in terms of $n_i$ and $\varepsilon$ \par \note{Remember, $\varepsilon$ is the correction constant in our approximation of $\log_2(1 + a)$.} \begin{solution} \begin{equation*} \log_2(r_f) ~=~ \log_2(\frac{1}{\sqrt{n_f}}) ~=~ \frac{-1}{2}\log_2(n_f) ~\approx~ \frac{-1}{2}\left( \frac{n_i}{2^{23}} + \varepsilon - 127 \right) \end{equation*} \end{solution} \vfill \problem{} Let's call the \say{magic number} in the code above $\kappa$, so that \begin{equation*} \texttt{Q\_sqrt}(n_f) = \kappa - (n_i \div 2) \end{equation*} Use problems \ref{num:convert} and \ref{num:finala} to show that $\texttt{Q\_sqrt}(n_f) \approx r_i$. \par \begin{solution} From \ref{convert}, we know that \begin{equation*} \log_2(r_f) \approx \frac{r_i}{2^{23}} + \varepsilon - 127 \end{equation*} \note{ Our approximation of $\log_2(1+a)$ uses a fixed correction constant, \par so the $\varepsilon$ here is equivalent to the $\varepsilon$ in \ref{finala}. } Combining this with the result from \ref{finala}, we get: \begin{align*} \frac{r_i}{2^{23}} + \varepsilon - 127 &~\approx~\frac{-1}{2}\left( \frac{n_i}{2^{23}} + \varepsilon - 127 \right) \\ \frac{r_i}{2^{23}} &~\approx~\frac{-1}{2}\left( \frac{n_i}{2^{23}} \right) + \frac{3}{2}(\varepsilon - 127) \\ r_i &~\approx~\frac{-1}{2}\left(n_i \right) + 2^{23}\frac{3}{2}(\varepsilon - 127) ~=~ 2^{23}\frac{3}{2}(\varepsilon - 127) - \frac{n_i}{2} \end{align*} \vspace{2mm} This is exactly what we need! If we set $\kappa$ to $\frac{2^{24}}{3}(\varepsilon - 127)$, then \begin{equation*} r_i ~\approx~ \kappa - (n_i \div 2) ~=~ \texttt{Q\_sqrt}(n_f) \end{equation*} \end{solution} \vfill \problem{} What is the exact value of $\kappa$ in terms of $\varepsilon$? \par \hint{Look at \ref{finalb}. We already found it!} \begin{solution} This problem makes sure our students see that $\kappa = \frac{2^{24}}{3}(\varepsilon - 127)$. \par See the solution to \ref{finalb}. \end{solution} \makeatletter \if@solutions\else \vspace{2cm} \fi\makeatother \pagebreak