#import "@local/handout:0.1.0": * #import "@preview/cetz:0.3.1" #import "@preview/cetz-plot:0.1.0": plot, chart = Integers and Floats #generic("Observation:") For small values of $x$, $log_2(1 + x)$ is approximately equal to $x$. \ Note that this equality is exact for $x = 0$ and $x = 1$, since $log_2(1) = 0$ and $log_2(2) = 1$. #v(5mm) We'll add the _correction term_ $epsilon$ to our approximation: $log_2(1 + a) approx a + epsilon$. \ This allows us to improve the average error of our linear approximation: #table( stroke: none, align: center, columns: (1fr, 1fr), inset: 5mm, [$log(1+x)$ and $x + 0$] + cetz.canvas({ import cetz.draw: * let f1(x) = calc.log(calc.abs(x + 1), base: 2) let f2(x) = x // Set-up a thin axis style set-style(axes: (stroke: .5pt, tick: (stroke: .5pt))) plot.plot( size: (7, 7), x-tick-step: 0.2, y-tick-step: 0.2, y-min: 0, y-max: 1, x-min: 0, x-max: 1, legend: none, axis-style: "scientific-auto", x-label: none, y-label: none, { let domain = (0, 1) plot.add( f1, domain: domain, label: $log(1+x)$, style: (stroke: ogrape), ) plot.add( f2, domain: domain, label: $x$, style: (stroke: oblue), ) }, ) }) + [ Max error: 0.086 \ Average error: 0.0573 ], [$log(1+x)$ and $x + 0.045$] + cetz.canvas({ import cetz.draw: * let f1(x) = calc.log(calc.abs(x + 1), base: 2) let f2(x) = x + 0.0450466 // Set-up a thin axis style set-style(axes: (stroke: .5pt, tick: (stroke: .5pt))) plot.plot( size: (7, 7), x-tick-step: 0.2, y-tick-step: 0.2, y-min: 0, y-max: 1, x-min: 0, x-max: 1, legend: none, axis-style: "scientific-auto", x-label: none, y-label: none, { let domain = (0, 1) plot.add( f1, domain: domain, label: $log(1+x)$, style: (stroke: ogrape), ) plot.add( f2, domain: domain, label: $x$, style: (stroke: oblue), ) }, ) }) + [ Max error: 0.041 \ Average error: 0.0254 ], ) A suitiable value of $epsilon$ can be found using calculus or with computational trial-and-error. \ We won't bother with this---we'll simply leave the correction term as an opaque constant $epsilon$. #v(1fr) #note( type: "Note", [ "Average error" above is simply the area of the region between the two graphs: $ integral_0^1 abs( #v(1mm) log(1+x) - (x+epsilon) #v(1mm)) $ Feel free to ignore this note, it isn't a critical part of this handout. ], ) #pagebreak() #problem(label: "convert") Use the fact that $log_2(1 + a) approx a + epsilon$ to approximate $log_2(x_f)$ in terms of $x_i$. \ Namely, show that $ log_2(x_f) = (x_i) / (2^23) - 127 + epsilon $ #note([ In other words, we're finding an expression for $x$ as a float in terms of $x$ as an int. ]) #solution([ Let $E$ and $F$ be the exponent and float bits of $x_f$. \ We then have: $ log_2(x_f) &= log_2 ( 2^(E-127) times (1 + (F) / (2^23)) ) \ &= E - 127 + log_2(1 + F / (2^23)) \ & approx E-127 + F / (2^23) + epsilon \ &= 1 / (2^23)(2^23 E + F) - 127 + epsilon \ &= 1 / (2^23)(x_i) - 127 + epsilon $ ]) #v(1fr) #problem() Using basic log rules, rewrite $log_2(1 / sqrt(x))$ in terms of $log_2(x)$. #solution([ $ log_2(1 / sqrt(x)) = (-1) / (2)log_2(x) $ ]) #v(1fr)