Compare commits
2 Commits
0653bd5b8e
...
8ef2d1cae8
Author | SHA1 | Date | |
---|---|---|---|
8ef2d1cae8 | |||
126dd70d70 |
@ -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),
|
||||
),
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user