201 lines
4.2 KiB
Typst
201 lines
4.2 KiB
Typst
#import "@local/handout:0.1.0": *
|
|
#import "@preview/cetz:0.3.1"
|
|
|
|
= Floats
|
|
#definition()
|
|
_Binary decimals_#footnote["decimal" is a misnomer, but that's ok.] are very similar to base-10 decimals. \
|
|
In base 10, we interpret place value as follows:
|
|
- $0.1 = 10^(-1)$
|
|
- $0.03 = 3 times 10^(-2)$
|
|
- $0.0208 = 2 times 10^(-2) + 8 times 10^(-4)$
|
|
|
|
#v(5mm)
|
|
|
|
We can do the same in base 2:
|
|
- $#text([`0.1`]) = 2^(-1) = 0.5$
|
|
- $#text([`0.011`]) = 2^(-2) + 2^(-3) = 0.375$
|
|
- $#text([`101.01`]) = 5.125$
|
|
|
|
#v(5mm)
|
|
|
|
#problem()
|
|
Rewrite the following binary decimals in base 10: \
|
|
#note([You may leave your answer as a fraction.])
|
|
- `1011.101`
|
|
- `110.1101`
|
|
|
|
|
|
#v(1fr)
|
|
#pagebreak()
|
|
|
|
#definition()
|
|
Another way we can interpret a bit string is as a _signed floating-point decimal_, or a `float` for short. \
|
|
Floats represent a subset of the real numbers, and are interpreted as follows: \
|
|
#note([The following only applies to floats that consist of 32 bits. We won't encounter any others today.])
|
|
|
|
#align(
|
|
center,
|
|
box(
|
|
inset: 2mm,
|
|
cetz.canvas({
|
|
import cetz.draw: *
|
|
|
|
let chars = (
|
|
`0`,
|
|
`b`,
|
|
`0`,
|
|
`_`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`_`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`_`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`_`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
`0`,
|
|
)
|
|
|
|
let x = 0
|
|
for c in chars {
|
|
content((x, 0), c)
|
|
x += 0.25
|
|
}
|
|
|
|
let y = -0.4
|
|
line((0.3, y), (0.65, y))
|
|
content((0.45, y - 0.2), [s])
|
|
|
|
line((0.85, y), (2.9, y))
|
|
content((1.9, y - 0.2), [exponent])
|
|
|
|
line((3.10, y), (9.4, y))
|
|
content((6.3, y - 0.2), [fraction])
|
|
}),
|
|
),
|
|
)
|
|
|
|
- The first bit denotes the sign of the float's value
|
|
We'll label it $s$. \
|
|
If $s = #text([`1`])$, this float is negative; if $s = #text([`0`])$, it is positive.
|
|
|
|
- The next eight bits represent the _exponent_ of this float.
|
|
#note([(we'll see what that means soon)]) \
|
|
We'll call the value of this eight-bit binary integer $E$. \
|
|
Naturally, $0 <= E <= 255$ #note([(since $E$ consist of eight bits.)])
|
|
|
|
- The remaining 23 bits represent the _fraction_ of this float, which we'll call $F$. \
|
|
These 23 bits are interpreted as the fractional part of a binary decimal. \
|
|
For example, the bits `0b10100000_00000000_00000000` represents $0.5 + 0.125 = 0.625$.
|
|
|
|
|
|
#problem(label: "floata")
|
|
Consider `0b01000001_10101000_00000000_00000000`. \
|
|
Find the $s$, $E$, and $F$ we get if we interpret this bit string as a `float`. \
|
|
#note([Leave $F$ as a sum of powers of two.])
|
|
|
|
#solution([
|
|
$s = 0$ \
|
|
$E = 258$ \
|
|
$F = 2^31+2^19 = 2,621,440$
|
|
])
|
|
|
|
#v(1fr)
|
|
|
|
|
|
#definition(label: "floatdef")
|
|
The final value of a float with sign $s$, exponent $E$, and fraction $F$ is
|
|
|
|
$
|
|
(-1)^s times 2^(E - 127) times (1 + F / (2^(23)))
|
|
$
|
|
|
|
Notice that this is very similar to decimal scientific notation, which is written as
|
|
|
|
$
|
|
(-1)^s times 10^(e) times (f)
|
|
$
|
|
|
|
#problem()
|
|
Consider `0b01000001_10101000_00000000_00000000`. \
|
|
This is the same bit string we used in @floata. \
|
|
|
|
#v(2mm)
|
|
|
|
What value do we get if we interpret this bit string as a float? \
|
|
#hint([$21 div 16 = 1.3125$])
|
|
|
|
#solution([
|
|
This is 21:
|
|
$
|
|
2^(131) times (1 + (2^(21) + 2^(19)) / (2^(23)))
|
|
= 2^(4) times (1 + 0.25 + 0.0625)
|
|
= 16 times (1.3125)
|
|
= 21
|
|
$
|
|
])
|
|
|
|
#v(1fr)
|
|
#pagebreak()
|
|
|
|
#problem()
|
|
Encode $12.5$ as a float. \
|
|
#hint([$12.5 div 8 = 1.5625$])
|
|
|
|
#solution([
|
|
$
|
|
12.5
|
|
= 8 times 1.5625
|
|
= 2^(3) times (1 + (0.5 + 0.0625))
|
|
= 2^(130) times (1 + (2^(22) + 2^(19)) / (2^(23)))
|
|
$
|
|
|
|
which is `0b01000001_01001000_00000000_00000000`. \
|
|
])
|
|
|
|
|
|
#v(1fr)
|
|
|
|
#definition()
|
|
Say we have a bit string $x$. \
|
|
We'll let $x_f$ denote the value we get if we interpret $x$ as a float, \
|
|
and we'll let $x_i$ denote the value we get if we interpret $x$ an integer.
|
|
|
|
#problem()
|
|
Let $x = #text[`0b01000001_01001000_00000000_00000000`]$. \
|
|
What are $x_f$ and $x_i$? #note([As always, you may leave big numbers as powers of two.])
|
|
#solution([
|
|
$x_f = 12.5$
|
|
|
|
#v(2mm)
|
|
|
|
$x_i = 2^30 + 2^24 + 2^22 + 2^19 = 11,095,237,632$
|
|
])
|
|
|
|
#v(1fr)
|