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.
|
/// If false, hide instructor info.
|
||||||
///
|
///
|
||||||
@ -60,7 +60,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#let instructornote(content) = {
|
#let instructornote(content) = {
|
||||||
let c = oteal
|
|
||||||
if_solutions(
|
if_solutions(
|
||||||
align(
|
align(
|
||||||
center,
|
center,
|
||||||
@ -68,8 +67,8 @@
|
|||||||
block(
|
block(
|
||||||
width: 100%,
|
width: 100%,
|
||||||
breakable: false,
|
breakable: false,
|
||||||
fill: c,
|
fill: oblue,
|
||||||
stroke: c + 2pt,
|
stroke: oblue + 2pt,
|
||||||
inset: 1.5mm,
|
inset: 1.5mm,
|
||||||
align(left, text(fill: white, weight: "bold", [Instructor note:])),
|
align(left, text(fill: white, weight: "bold", [Instructor note:])),
|
||||||
),
|
),
|
||||||
@ -78,8 +77,8 @@
|
|||||||
width: 100%,
|
width: 100%,
|
||||||
height: auto,
|
height: auto,
|
||||||
breakable: false,
|
breakable: false,
|
||||||
fill: c.lighten(80%).desaturate(10%),
|
fill: oblue.lighten(80%).desaturate(10%),
|
||||||
stroke: c + 2pt,
|
stroke: oblue + 2pt,
|
||||||
inset: 3mm,
|
inset: 3mm,
|
||||||
align(left, content),
|
align(left, content),
|
||||||
),
|
),
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
#import "@local/handout:0.1.0": *
|
#import "@local/handout:0.1.0": *
|
||||||
|
|
||||||
// Why is division expensive?
|
// Intro:
|
||||||
|
// - we don't need signed ints
|
||||||
|
// - Why is division expensive?
|
||||||
// Add a few problems add/multiplying/dividing floats
|
// Add a few problems add/multiplying/dividing floats
|
||||||
|
// - Spend more time on left-shift
|
||||||
//
|
//
|
||||||
// Spend more time on left-shift
|
// Another look:
|
||||||
// Highlight that left-shift divides the exponent by two!
|
// - Highlight that left-shift divides the exponent by two
|
||||||
|
// - Highlight that log(ri) is already in its integer representation
|
||||||
//
|
//
|
||||||
// Floats vs fixed point
|
// Bonus:
|
||||||
// Float density
|
// - Floats vs fixed point
|
||||||
// Find non-floatable rational numbers
|
// - Float density
|
||||||
|
// - Find non-floatable rational numbers
|
||||||
|
// - What if we use `n`-bit floats?
|
||||||
|
|
||||||
#show: doc => handout(
|
#show: doc => handout(
|
||||||
doc,
|
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
|
log_2(r_f) approx (r_i) / (2^23) + epsilon - 127
|
||||||
$
|
$
|
||||||
|
|
||||||
#note[
|
Combining this with the result from @finala, we get:
|
||||||
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:
|
|
||||||
$
|
$
|
||||||
(r_i) / (2^23) + epsilon - 127
|
(r_i) / (2^23) + epsilon - 127
|
||||||
&approx (-1) / (2) ( (n_i) / (2^23) + epsilon - 127) \
|
&approx (-1) / (2) ( (n_i) / (2^23) + epsilon - 127) \
|
||||||
(r_i) / (2^23)
|
(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
|
r_i
|
||||||
&approx (-1) / 2 (n_i) + 2^23 3 / 2(epsilon - 127)
|
&approx (-1) / 2 (n_i) + 2^23 3 / 2(127 - epsilon)
|
||||||
= 2^23 3 / 2 (epsilon - 127) - (n_i) / 2
|
= 2^23 3 / 2 (127 - epsilon) - (n_i) / 2
|
||||||
$
|
$
|
||||||
|
|
||||||
#v(2mm)
|
#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)
|
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)
|
#v(1fr)
|
||||||
|
|
||||||
#problem()
|
#problem(label: "finalc")
|
||||||
What is the exact value of $kappa$ in terms of $epsilon$? \
|
What is the exact value of $kappa$ in terms of $epsilon$? \
|
||||||
#hint[Look at @finalb. We already found it!]
|
#hint[Look at @finalb. We already found it!]
|
||||||
|
|
||||||
#solution[
|
#solution[
|
||||||
This problem makes sure our students see that
|
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.
|
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))
|
#if_no_solutions(v(2cm))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user