Compare commits

..

2 Commits

Author SHA1 Message Date
8ef2d1cae8
FIR draft
Some checks failed
CI / Typos (pull_request) Failing after 7s
CI / Typst formatting (pull_request) Successful in 5s
CI / Build (pull_request) Has been skipped
2025-02-10 09:41:05 -08:00
126dd70d70
Tweak lib 2025-02-10 09:41:01 -08:00
3 changed files with 55 additions and 25 deletions

View File

@ -1,4 +1,4 @@
#import "misc.typ": ored, oteal
#import "misc.typ": ored, oblue
/// If false, hide instructor info.
///
@ -60,7 +60,6 @@
}
#let instructornote(content) = {
let c = oteal
if_solutions(
align(
center,
@ -68,8 +67,8 @@
block(
width: 100%,
breakable: false,
fill: c,
stroke: c + 2pt,
fill: oblue,
stroke: oblue + 2pt,
inset: 1.5mm,
align(left, text(fill: white, weight: "bold", [Instructor note:])),
),
@ -78,8 +77,8 @@
width: 100%,
height: auto,
breakable: false,
fill: c.lighten(80%).desaturate(10%),
stroke: c + 2pt,
fill: oblue.lighten(80%).desaturate(10%),
stroke: oblue + 2pt,
inset: 3mm,
align(left, content),
),

View File

@ -1,14 +1,20 @@
#import "@local/handout:0.1.0": *
// Why is division expensive?
// Add a few problems add/multiplying/dividing floats
// Intro:
// - we don't need signed ints
// - Why is division expensive?
// Add a few problems add/multiplying/dividing floats
// - Spend more time on left-shift
//
// Spend more time on left-shift
// Highlight that left-shift divides the exponent by two!
// Another look:
// - Highlight that left-shift divides the exponent by two
// - Highlight that log(ri) is already in its integer representation
//
// Floats vs fixed point
// Float density
// Find non-floatable rational numbers
// Bonus:
// - Floats vs fixed point
// - Float density
// - Find non-floatable rational numbers
// - What if we use `n`-bit floats?
#show: doc => handout(
doc,

View File

@ -85,25 +85,20 @@ Use @convert and @finala to show that $#text[`Q_sqrt`] (n_f) approx r_i$
log_2(r_f) approx (r_i) / (2^23) + epsilon - 127
$
#note[
Our approximation of $log_2(1+a)$ uses a fixed correction constant, \
so the $epsilon$ here is equivalent to the $epsilon$ in @finala.
]
Combining this with the result from \ref{finala}, we get:
Combining this with the result from @finala, we get:
$
(r_i) / (2^23) + epsilon - 127
&approx (-1) / (2) ( (n_i) / (2^23) + epsilon - 127) \
(r_i) / (2^23)
&approx (-1) / (2) ( (n_i) / (2^23)) + 3 / 2 (epsilon - 127) \
&approx (-1) / (2) ( (n_i) / (2^23)) + 3 / 2 (127 - epsilon) \
r_i
&approx (-1) / 2 (n_i) + 2^23 3 / 2(epsilon - 127)
= 2^23 3 / 2 (epsilon - 127) - (n_i) / 2
&approx (-1) / 2 (n_i) + 2^23 3 / 2(127 - epsilon)
= 2^23 3 / 2 (127 - epsilon) - (n_i) / 2
$
#v(2mm)
This is exactly what we need! If we set $kappa$ to $(2^24)/3 (epsilon - 127)$, then
This is exactly what we need! If we set $kappa$ to $(3 times 2^22) (127-epsilon)$, then
$
r_i approx kappa - (n_i div 2) = #text[`Q_sqrt`] (n_f)
$
@ -111,14 +106,44 @@ Use @convert and @finala to show that $#text[`Q_sqrt`] (n_f) approx r_i$
#v(1fr)
#problem()
#problem(label: "finalc")
What is the exact value of $kappa$ in terms of $epsilon$? \
#hint[Look at @finalb. We already found it!]
#solution[
This problem makes sure our students see that
$kappa = 2^23 3/2 (127 - epsilon)$. \
$kappa = (3 times 2^22) (127 - epsilon)$. \
See the solution to @finalb.
]
#v(2cm)
#pagebreak()
#remark()
In @finalc we saw that $kappa = (3 times 2^22) (127 - epsilon)$. \
Looking at the code again, we see that $kappa = #text[`0x5f3759df`]$ in _Quake_:
#v(2mm)
```c
float Q_rsqrt( float number ) {
long i = * ( long * ) &number;
i = 0x5f3759df - ( i >> 1 );
return * ( float * ) &i;
}
```
#v(2mm)
Using a calculator and some basic algebra, we can find the $epsilon$ this code uses: \
#note[Remember, #text[`0x5f3759df`] is $6240089$ in hexadecimal.]
$
(3 times 2^22) (127 - epsilon) &= 6240089 \
(127 - epsilon) &= 126.955 \
epsilon &= 0.0450466
$
So, $0.045$ is the $epsilon$ used by Quake. \
This constant was likely generated by trial-and-error, and is fairly close to the ideal $epsilon$.
#if_no_solutions(v(2cm))