Compare commits
4 Commits
8ef2d1cae8
...
0653bd5b8e
Author | SHA1 | Date | |
---|---|---|---|
0653bd5b8e | |||
ecb70b9ea8 | |||
8f4bbff550 | |||
e5d3fbee19 |
@ -1,4 +1,4 @@
|
|||||||
#import "misc.typ": ored, oblue
|
#import "misc.typ": ored, oteal
|
||||||
|
|
||||||
/// If false, hide instructor info.
|
/// If false, hide instructor info.
|
||||||
///
|
///
|
||||||
@ -60,6 +60,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#let instructornote(content) = {
|
#let instructornote(content) = {
|
||||||
|
let c = oteal
|
||||||
if_solutions(
|
if_solutions(
|
||||||
align(
|
align(
|
||||||
center,
|
center,
|
||||||
@ -67,8 +68,8 @@
|
|||||||
block(
|
block(
|
||||||
width: 100%,
|
width: 100%,
|
||||||
breakable: false,
|
breakable: false,
|
||||||
fill: oblue,
|
fill: c,
|
||||||
stroke: oblue + 2pt,
|
stroke: c + 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:])),
|
||||||
),
|
),
|
||||||
@ -77,8 +78,8 @@
|
|||||||
width: 100%,
|
width: 100%,
|
||||||
height: auto,
|
height: auto,
|
||||||
breakable: false,
|
breakable: false,
|
||||||
fill: oblue.lighten(80%).desaturate(10%),
|
fill: c.lighten(80%).desaturate(10%),
|
||||||
stroke: oblue + 2pt,
|
stroke: c + 2pt,
|
||||||
inset: 3mm,
|
inset: 3mm,
|
||||||
align(left, content),
|
align(left, content),
|
||||||
),
|
),
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
#import "@local/handout:0.1.0": *
|
#import "@local/handout:0.1.0": *
|
||||||
|
|
||||||
// Intro:
|
// Why is division expensive?
|
||||||
// - we don't need signed ints
|
// Add a few problems add/multiplying/dividing floats
|
||||||
// - Why is division expensive?
|
|
||||||
// Add a few problems add/multiplying/dividing floats
|
|
||||||
// - Spend more time on left-shift
|
|
||||||
//
|
//
|
||||||
// Another look:
|
// Spend more time on left-shift
|
||||||
// - 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
|
|
||||||
//
|
//
|
||||||
// Bonus:
|
// Floats vs fixed point
|
||||||
// - Floats vs fixed point
|
// Float density
|
||||||
// - Float density
|
// Find non-floatable rational numbers
|
||||||
// - Find non-floatable rational numbers
|
|
||||||
// - What if we use `n`-bit floats?
|
|
||||||
|
|
||||||
#show: doc => handout(
|
#show: doc => handout(
|
||||||
doc,
|
doc,
|
||||||
|
@ -85,20 +85,25 @@ 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
|
||||||
$
|
$
|
||||||
|
|
||||||
Combining this with the result from @finala, we get:
|
#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:
|
||||||
$
|
$
|
||||||
(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 (127 - epsilon) \
|
&approx (-1) / (2) ( (n_i) / (2^23)) + 3 / 2 (epsilon - 127) \
|
||||||
r_i
|
r_i
|
||||||
&approx (-1) / 2 (n_i) + 2^23 3 / 2(127 - epsilon)
|
&approx (-1) / 2 (n_i) + 2^23 3 / 2(epsilon - 127)
|
||||||
= 2^23 3 / 2 (127 - epsilon) - (n_i) / 2
|
= 2^23 3 / 2 (epsilon - 127) - (n_i) / 2
|
||||||
$
|
$
|
||||||
|
|
||||||
#v(2mm)
|
#v(2mm)
|
||||||
|
|
||||||
This is exactly what we need! If we set $kappa$ to $(3 times 2^22) (127-epsilon)$, then
|
This is exactly what we need! If we set $kappa$ to $(2^24)/3 (epsilon - 127)$, 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)
|
||||||
$
|
$
|
||||||
@ -106,44 +111,14 @@ Use @convert and @finala to show that $#text[`Q_sqrt`] (n_f) approx r_i$
|
|||||||
|
|
||||||
#v(1fr)
|
#v(1fr)
|
||||||
|
|
||||||
#problem(label: "finalc")
|
#problem()
|
||||||
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 = (3 times 2^22) (127 - epsilon)$. \
|
$kappa = 2^23 3/2 (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