From 4f4675a164410048a4490497ca04b922de6f5e97 Mon Sep 17 00:00:00 2001 From: Mark Date: Sat, 8 Feb 2025 14:54:40 -0800 Subject: [PATCH] Quake edits --- src/Advanced/Fast Inverse Root/main.tex | 34 +-- .../Fast Inverse Root/parts/4 int.tex | 101 +++++++++ .../parts/{4 float.tex => 5 float.tex} | 203 ++++++++---------- .../{5 approximate.tex => 6 approximate.tex} | 26 +-- .../parts/{6 quake.tex => 7 quake.tex} | 50 +++-- 5 files changed, 242 insertions(+), 172 deletions(-) create mode 100644 src/Advanced/Fast Inverse Root/parts/4 int.tex rename src/Advanced/Fast Inverse Root/parts/{4 float.tex => 5 float.tex} (50%) rename src/Advanced/Fast Inverse Root/parts/{5 approximate.tex => 6 approximate.tex} (67%) rename src/Advanced/Fast Inverse Root/parts/{6 quake.tex => 7 quake.tex} (55%) diff --git a/src/Advanced/Fast Inverse Root/main.tex b/src/Advanced/Fast Inverse Root/main.tex index 2b2176f..135b9a4 100755 --- a/src/Advanced/Fast Inverse Root/main.tex +++ b/src/Advanced/Fast Inverse Root/main.tex @@ -37,28 +37,28 @@ \maketitle - - \begin{center} - \begin{minipage}{6cm} - Dad says that anyone who can't use - a slide rule is a cultural illiterate - and should not be allowed to vote. - - \vspace{1ex} - - \textit{Have Space Suit --- Will Travel, 1958} - \end{minipage} - \end{center} - \hfill + %\begin{center} + %\begin{minipage}{6cm} + % Dad says that anyone who can't use + % a slide rule is a cultural illiterate + %and should not be allowed to vote. + % + % \vspace{1ex} + % + % \textit{Have Space Suit --- Will Travel, 1958} + %\end{minipage} + %\end{center} + %\hfill %\input{parts/0 logarithms.tex} %\input{parts/1 intro.tex} %\input{parts/2 multiplication.tex} %\input{parts/3 division.tex} - \pagebreak - \input{parts/4 float.tex} - \input{parts/5 approximate.tex} - \input{parts/6 quake.tex} + %\pagebreak + \input{parts/4 int.tex} + \input{parts/5 float.tex} + \input{parts/6 approximate.tex} + \input{parts/7 quake.tex} % Make sure the slide rule is on an odd page, % so that double-sided prints won't require diff --git a/src/Advanced/Fast Inverse Root/parts/4 int.tex b/src/Advanced/Fast Inverse Root/parts/4 int.tex new file mode 100644 index 0000000..891553c --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/4 int.tex @@ -0,0 +1,101 @@ +\section{Integers} + +\definition{} +A \textit{bit string} is a string of binary digits. \par +In this handout, we'll denote bit strings with the prefix \texttt{0b}. \par +That is, $1010 =$ \say{one thousand and one,} while $\texttt{0b1001} = 2^3 + 2^0 = 9$ + +\vspace{2mm} +We will seperate long bit strings with underscores for readability. \par +Underscores have no meaning: $\texttt{0b1111\_0000} = \texttt{0b11110000}$. + +\problem{} +What is the value of the following bit strings, if we interpret them as integers in base 2? \par +\begin{itemize} + \item \texttt{0b0001\_1010} + \item \texttt{0b0110\_0001} +\end{itemize} + +\begin{solution} + \begin{itemize} + \item $\texttt{0b0001\_1010} = 2 + 8 + 16 = 26$ + \item $\texttt{0b0110\_0001} = 1 + 32 + 64 = 95$ + \end{itemize} +\end{solution} + +\vfill +\pagebreak + + +\definition{} +We can interpret a bit string in any number of ways. \par +One such interpretation is the \textit{signed integer}, or \texttt{int} for short. \par +\texttt{ints} allow us to represent negative and positive integers using 32-bit strings. + +\vspace{2mm} + +The first bit of an \texttt{int} tells us its sign: +\begin{itemize} + \item if the first bit is \texttt{1}, the \textit{int} represents a negative number; + \item if the first bit is \texttt{0}, it represents a positive number. +\end{itemize} +We do not need negative numbers today, so we will assume that the first bit is always zero. \par +\note{If you'd like to know how negative integers are written, look up \say{two's complement} after class.} + +\vspace{2mm} + +The value of a positive signed \texttt{long} is simply the value of its binary digits: +\begin{itemize} + \item $\texttt{0b00000000\_00000000\_00000000\_00000000} = 0$ + \item $\texttt{0b00000000\_00000000\_00000000\_00000011} = 3$ + \item $\texttt{0b00000000\_00000000\_00000000\_00100000} = 32$ + \item $\texttt{0b00000000\_00000000\_00000000\_10000010} = 130$ +\end{itemize} + +\problem{} +What is the largest number we can represent with a 32-bit \texttt{int}? + +\begin{solution} + $\texttt{0b01111111\_11111111\_11111111\_11111111} = 2^{31}$ +\end{solution} + +\vfill + +\problem{} +What is the smallest possible number we can represented with a 32-bit \texttt{int}? \par +\hint{ + You do not need to know \textit{how} negative numbers are represented. \par + Assume that we do not skip any integers, and don't forget about zero. +} + +\begin{solution} + There are $2^{64}$ possible 32-bit patterns, + of which 1 represents zero and $2^{31}$ represent positive numbers. + We therefore have access to $2^{64} - 1 - 2^{31}$ negative numbers, + giving us a minimum representable value of $-2^{31} + 1$. +\end{solution} + +\vfill + +\problem{} +Find the value of each of the following 32-bit \texttt{int}s: +\begin{itemize} + \item \texttt{0b00000000\_00000000\_00000101\_00111001} + \item \texttt{0b00000000\_00000000\_00000001\_00101100} + \item \texttt{0b00000000\_00000000\_00000100\_10110000} +\end{itemize} +\hint{The third conversion is easy---look carefully at the second.} + +\begin{solution} + \begin{itemize} + \item $\texttt{0b00000000\_00000000\_00000101\_00111001} = 1337$ + \item $\texttt{0b00000000\_00000000\_00000001\_00101100} = 300$ + \item $\texttt{0b00000000\_00000000\_00000010\_01011000} = 1200$ + \end{itemize} + + Notice that the third long is the second shifted left twice (i.e, multiplied by 4) +\end{solution} + +\vfill +\vfill +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/4 float.tex b/src/Advanced/Fast Inverse Root/parts/5 float.tex similarity index 50% rename from src/Advanced/Fast Inverse Root/parts/4 float.tex rename to src/Advanced/Fast Inverse Root/parts/5 float.tex index 515c1b3..af3139f 100644 --- a/src/Advanced/Fast Inverse Root/parts/4 float.tex +++ b/src/Advanced/Fast Inverse Root/parts/5 float.tex @@ -1,99 +1,44 @@ - -\section{\texttt{int}s and \texttt{float}s} +\section{Floats} \definition{} -A \textit{signed 32-bit integer} (equivalently, a \texttt{long int}) consists of thirty-two binary digits, \par -and is used represent a subset of the integers. - -\vspace{2mm} - -The first bit of a \texttt{long} tells us its sign: +\textit{Binary decimals}\footnotemark{} are very similar to base-10 decimals. \par +In base 10, we interpret place value as follows: \begin{itemize} - \item if the first bit of a \texttt{long} is \texttt{1}, it represents a negative number; - \item if the first bit is \texttt{0}, it represents a positive number. -\end{itemize} -We do not need negative numbers today, so we will assume that the first bit is always zero. \par -\note{If you'd like to know how negative integers are written, look up \say{two's complement} after class.} - -\vspace{2mm} - -We'll denote binary strings with the prefix \texttt{0b}. \par -Underscores are added between every eight digits for readability, and have no meaning. - -\vspace{2mm} - - -The value of a positive signed \texttt{long} is simply the value of its binary digits. \par -For example: -\begin{itemize} - \item $\texttt{0b00000000\_00000000\_00000000\_00000000} = 0$ - \item $\texttt{0b00000000\_00000000\_00000000\_00000011} = 3$ - \item $\texttt{0b00000000\_00000000\_00000000\_00100000} = 32$ - \item $\texttt{0b00000000\_00000000\_00000000\_10000010} = 130$ + \item $0.1 = 10^{-1}$ + \item $0.03 = 3 \ \times 10^{-2}$ + \item $0.0008 = 8 \times 10^{-4}$ \end{itemize} -Remember---we only need positive integers today. Assume the \say{sign} bit is always \texttt{0}. +\footnotetext{this is a misnomer, but that's ok.} -\problem{} -What is the largest number that can be represented with a \texttt{long}? +\vspace{5mm} -\begin{solution} - $\texttt{0b01111111\_11111111\_11111111\_11111111} = 2^{31}$ -\end{solution} - -\vfill - - - -\problem{} -What is the smallest possible number that can be represented with a \texttt{long}? \par -\hint{ - You do not need to know \textit{how} negative numbers are represented. \par - Assume that we do not skip any integers, and don't forget about zero. -} - -\begin{solution} - There are $2^{64}$ possible 32-bit patterns, - of which 1 represents zero and $2^{31}$ represent positive numbers. - - \vspace{2mm} - - We therefore have access to $2^{64} - 1 - 2^{31}$ negative numbers, - giving us a minimum representable value of $-2^{31} + 1$. -\end{solution} - -\problem{} -What is the value of the following longs? +We can do the same in base 2: \begin{itemize} - \item \texttt{0b00000000\_00000000\_00000101\_00111001} - \item \texttt{0b00000000\_00000000\_00000001\_00101100} - \item \texttt{0b00000000\_00000000\_00000100\_10110000} + \item $\texttt{0.1} = 2^{-1} = 0.5$ + \item $\texttt{0.011} = 2^{-2} + 2^{-3} = 0.375$ + \item $\texttt{101.01} = 5.125$ \end{itemize} -\hint{The third conversion is easy---look carefully at the second.} -\begin{solution} - \begin{itemize} - \item $\texttt{0b00000000\_00000000\_00000101\_00111001} = 1337$ - \item $\texttt{0b00000000\_00000000\_00000001\_00101100} = 300$ - \item $\texttt{0b00000000\_00000000\_00000010\_01011000} = 1200$ - \end{itemize} +\vspace{5mm} - Notice that the third long is the second shifted left twice (i.e, multiplied by 4) -\end{solution} +\problem{} +Rewrite the following binary decimals in base 10: \par +\note{You may leave your answer as a fraction} +\begin{itemize} + \item $\texttt{1011.101}$ + \item $\texttt{110.1101}$ +\end{itemize} \vfill \pagebreak - \definition{} -A \textit{signed 32-bit floating-point decimal} (equivalently, a \textit{float}) -consists of 32 binary digits, and is used to represent a subset of the real numbers. -These 32 bits are interpreted as follows: - +Another way we can interpret a bit string is as a \textit{signed floating-point decimal}, or a \texttt{float} for short. \par +Floats represent a subset of the real numbers, and are interpreted as follows: \par +\note{The following only applies to floats that consist of 32 bits. We won't encounter any others today.} \begin{center} \begin{tikzpicture} - - \node[anchor=south west] at (0, 0) {\texttt{\texttt{0}}}; \node[anchor=south west] at (0.25, 0) {\texttt{\texttt{b}}}; \node[anchor=south west] at (0.50, 0) {\texttt{\texttt{0}}}; @@ -144,76 +89,98 @@ These 32 bits are interpreted as follows: \end{tikzpicture} \end{center} -In other words: -\begin{itemize}[itemsep = 1mm] +\begin{itemize}[itemsep = 2mm] \item The first bit denotes the sign of the float's value. We'll label it $s$. \par - If $s = 1$, this float is negative; if $s = 0$, it is positive. + If $s = \texttt{1}$, this float is negative; if $s = \texttt{0}$, it is positive. - \item The next 8 bits represent the \textit{exponent} of this float. \par - We'll call the value of these eight bits $E$. \par - Naturally, $0 \leq E \leq 255$ + \item The next eight bits represent the \textit{exponent} of this float. \note{(we'll see what that means soon)}\par + We'll call the value of this eight-bit binary integer $E$. \par + Naturally, $0 \leq E \leq 255$ \note{(since $E$ consist of eight bits.)} - \item The remaining 23 bits represent the \textit{fraction} of this float. \par + \item The remaining 23 bits represent the \textit{fraction} of this float, which we'll call $F$. \par These 23 bits are interpreted as the fractional part of a binary decimal. \par For example, the bits \texttt{0b1010000\_00000000\_00000000} represents $0.5 + 0.125 = 0.625$. \end{itemize} +\problem{} +Consider \texttt{0b01000001\_10101000\_00000000\_00000000}. \par +Find the $s$, $E$, and $F$ we get if we interpret this bit string as a \texttt{float}. \par +\note[Note]{Leave $F$ as a sum of powers of two.} -\vspace{2mm} +\begin{solution} + $s = 0$ \par + $E = 258$ \par + $F = 2^{31}+2^{19} = 2,621,440$ +\end{solution} +\vfill + + +\definition{} The final value of a float with sign $s$, exponent $E$, and fraction $F$ is \begin{equation*} (-1)^s ~\times~ 2^{E - 127} ~\times~ \left(1 + \frac{F}{2^{23}}\right) \end{equation*} - Notice that this is very similar to decimal scientific notation, which is written as \begin{equation*} - (\pm 1) ~\times~ 10^{e} ~\times~ (f) + (-1)^s ~\times~ 10^{e} ~\times~ (f) \end{equation*} +\problem{} +Consider \texttt{0b01000001\_10101000\_00000000\_00000000}. \par +This is the same bit string we used in \ref{floata}. \par + +\vspace{2mm} + +What value do we get if we interpret this bit string as a float? \par +\hint{$21 \div 16 = 1.3125$} + +\begin{solution} + This is 21: + \begin{equation*} + 2^{131} \times \biggl(1 + \frac{2^{21} + 2^{19}}{2^{23}}\biggr) + ~=~ 2^{4} \times (1 + 0.25 + 0.0625) + ~=~ 16 \times (1.3125) + ~=~ 21 + \end{equation*} +\end{solution} + \vfill \pagebreak -\problem{} -What is the value of \texttt{0b01000001\_10101000\_00000000\_00000000} if it is interpreted as a float? \par -\hint{$21 \div 16 = 1.3125$} - -\begin{solution} - This is 21: - \begin{align*} - &=~ 2^{131} \times \biggl(1 + \frac{2^{21} + 2^{19}}{2^{23}}\biggr) \\ - &=~ 2^{4} \times (1 + 0.25 + 0.0625) \\ - &=~ 16 \times (1.3125) \\ - &=~ 21 - \end{align*} -\end{solution} - -\vfill - \problem{} Encode $12.5$ as a float. \par \hint{$12.5 \div 8 = 1.5625$} -\vspace{2mm} - -What is the value of the resulting 32 bits if they are interpreted as a long? \par -\hint{A sum of powers of two is fine.} - \begin{solution} - \begin{align*} + \begin{equation*} 12.5 - &=~ 8 \times 1.5625 \\ - &=~ 2^{3} \times \biggl(1 + (0.5 + 0.0625)\biggr) \\ - &=~ 2^{130} \times \biggl(1 + \frac{2^{22} + 2^{19}}{2^{23}}\biggr) - \end{align*} + ~=~ 8 \times 1.5625 + ~=~ 2^{3} \times \biggl(1 + (0.5 + 0.0625)\biggr) + ~=~ 2^{130} \times \biggl(1 + \frac{2^{22} + 2^{19}}{2^{23}}\biggr) + \end{equation*} - \linehack{} - - This is \texttt{0b01000001\_01001000\_00000000\_00000000}, \par - which is $2^{30} + 2^{24} + 2^{22} + 2^{19} = 11,095,237,632$ + which is \texttt{0b01000001\_01001000\_00000000\_00000000}. \par \end{solution} \vfill + +\definition{} +Say we have a bit string $x$. \par +We'll let $x_f$ denote the value we get if we interpret $x$ as a float, \par +and we'll let $x_i$ denote the value we get if we interpret $x$ an integer. + +\problem{} +Let $x = \texttt{0b01000001\_01001000\_00000000\_00000000}$. \par +What are $x_f$ and $x_i$? \note{As always, you may leave big numbers as powers of two.} +\begin{solution} + $x_f = 12.5$ \par + \vspace{2mm} + $x_i = 2^{30} + 2^{24} + 2^{22} + 2^{19} = 11,095,237,632$ +\end{solution} + +\vfill + \pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/5 approximate.tex b/src/Advanced/Fast Inverse Root/parts/6 approximate.tex similarity index 67% rename from src/Advanced/Fast Inverse Root/parts/5 approximate.tex rename to src/Advanced/Fast Inverse Root/parts/6 approximate.tex index e3678dd..bde946d 100644 --- a/src/Advanced/Fast Inverse Root/parts/5 approximate.tex +++ b/src/Advanced/Fast Inverse Root/parts/6 approximate.tex @@ -1,21 +1,5 @@ \section{Approximation} -\definition{} -Say we have a bit string $x$. \par -Let $x_f$ denote the value of $x$ interpreted as a float, \par -and let $x_i$ denote the value of $x$ interpreted as an integer. - -\problem{} -Let $x = \texttt{0b01000001\_01001000\_00000000\_00000000}$. \ -What are $x_f$ and $x_i$? - -\begin{solution} - $x_f = 12.5$ \par - \vspace{2mm} - $x_i = 2^{30} + 2^{24} + 2^{22} + 2^{19} = 11,095,237,632$ -\end{solution} - - \generic{Observation:} For small values of $a$, $\log_2(1 + a)$ is approximately equal to $a$. \par Note that this equality is exact for $a = 0$ and $a = 1$, since $\log_2(1) = 0$ and $\log_2(2) = 1$. @@ -27,7 +11,15 @@ We'll add a \say{correction term} $\varepsilon$ to this approximation, so that $ TODO: why? Graphs. \problem{} -Use the fact that $\log_2(1 + a) \approx a + \varepsilon$ to approximate $\log_2(x_f)$ in terms of $x_i$, \par +Use the fact that $\log_2(1 + a) \approx a + \varepsilon$ to approximate $\log_2(x_f)$ in terms of $x_i$. \par + +\vspace{5mm} + +Namely, show that +\begin{equation*} + \log_2(x_f) ~=~ \frac{1}{2^{23}}(x_i) - 127 + \varepsilon +\end{equation*} +for some error term $\varepsilon$ \begin{solution} diff --git a/src/Advanced/Fast Inverse Root/parts/6 quake.tex b/src/Advanced/Fast Inverse Root/parts/7 quake.tex similarity index 55% rename from src/Advanced/Fast Inverse Root/parts/6 quake.tex rename to src/Advanced/Fast Inverse Root/parts/7 quake.tex index 7626ad1..2cdbbae 100644 --- a/src/Advanced/Fast Inverse Root/parts/6 quake.tex +++ b/src/Advanced/Fast Inverse Root/parts/7 quake.tex @@ -1,13 +1,11 @@ \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; @@ -16,45 +14,55 @@ float Q_rsqrt( float number ) { } \end{lstlisting} -It defines a method \texttt{Q\_rsqrt} that consumes a float named \texttt{number} and quickly approximates its inverse -square root (in other words, \texttt{Q\_rsqrt} computes $1/\sqrt{\texttt{number}}$). +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{8mm} +\vspace{2mm} If we rewrite this using the notation we're familiar with, we get the following: - \begin{equation*} - \frac{1}{\sqrt{n_f}} \approx \kappa - (n_i \div 2) + \texttt{Q\_sqrt}(n_i) = 6240089 - (n_i \div 2) \approx \frac{1}{\sqrt{n_f}} \end{equation*} -Where $\kappa$ is the magic constant $6240089$ (which is \texttt{0x5f3759df} in hexadecimal) +$6240089$ is the decimal value of hex \texttt{0x5f3759df}. \par +It is a magic number hard-coded into the function. + +\vspace{2mm} + +Our goal in this section is to understand why this works. \par +How are we able to approximate $\frac{1}{\sqrt{x}}$ by only subtracting and dividing by two?? + +\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 + \problem{} Find the exact value of $\kappa$ in terms of $\varepsilon$. \par -\hint{Remember that $\varepsilon$ is the correction term in the approximation $\log_2(1 + a) = a + \varepsilon$.} - -\problem{} -Rewrite $\log_2(1 / \sqrt{x})$ in terms of $\log_2{x}$. +\note{Remember, $\varepsilon$ is the correction term in the approximation $\log_2(1 + a) = a + \varepsilon$.} \begin{solution} - Say $g_f = \frac{1}{\sqrt{n_f}}$---that is, $g_f$ is the value we want to compute. \par - Then: - + Say $g_f = \frac{1}{\sqrt{n_f}}$ (i.e, $g_f$ is the value we want to compute). We then have: \begin{align*} \log_2(g_f) &=\log_2(\frac{1}{\sqrt{n_f}}) \\ &=\frac{-1}{2}\log_2(n_f) \\ &=\frac{-1}{2}\left( \frac{n_i}{2^{23}} + \varepsilon - 127 \right) \end{align*} - But we also know that - \begin{align*} \log_2(g_f) &=\frac{g_i}{2^{23}} + \varepsilon - 127 \end{align*} - So, - \begin{align*} \frac{g_i}{2^{23}} + \varepsilon - 127 &=\frac{-1}{2}\left( \frac{n_i}{2^{23}} + \varepsilon - 127 \right) \\ @@ -65,7 +73,9 @@ Rewrite $\log_2(1 / \sqrt{x})$ in terms of $\log_2{x}$. &=2^{23}\frac{3}{2}(\varepsilon - 127) - \frac{n_i}{2} \end{align*} - thus, $\kappa = 2^{23}\frac{3}{2}(\varepsilon - 127)$. + and thus $\kappa = 2^{23}\frac{3}{2}(\varepsilon - 127)$. \end{solution} +\vfill + \pagebreak \ No newline at end of file