# Logarithm Approximation Precision
This cosument formally proves maximum absolute errors of approximated logarithm calculation to be used in Uniswap v2 protocol.
## Base-2 Logarithm Approximation
We approximate base-2 logarithm iteratively. Initial approximation for $\log_2 x$ is defined like this:
$$
l_0 (x) = \left\lfloor \log_2 x \right\rfloor
$$
So the initial approximation is just the logarithm rounded down, i.e. towards $-\infty$. The absolute error of the initial approximation is bounded like this:
$$
\varepsilon_0(x) = l_0 (x) - \log_2 x \in (-1;+0]
$$
Every next approximation is defined like this:
$$
l_{i+1}(x) = \left\lfloor \log_2 x \right\rfloor + \frac{1}{2} l_i \left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right)
$$
Here $\left\lfloor a \right\rfloor_b$ means $a$ rounded down to the closest factor of $b$.
The absolute error of this approximation is:
$$
\varepsilon_{i+1}(x) = l_{i+1} - \log_2 x =\\=
\left\lfloor \log_2 x \right\rfloor + \frac{1}{2} l_i \left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) - \log_2 \left(2^{\left\lfloor \log_2 x \right\rfloor}\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right) =\\=
\left\lfloor \log_2 x \right\rfloor + \frac{1}{2} l_i \left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) - \left\lfloor \log_2 x \right\rfloor - \log_2 \frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}} =\\=
\frac{1}{2} l_i \left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) - \log_2 \frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}} =\\=
\frac{1}{2} l_i \left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) - \frac{1}{2}\log_2\left(\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right)^2 =\\=
\frac{1}{2} \left(l_i \left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) - \log_2\left(\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right)^2\right)
$$
Let's note, that
$$
\log_2 x - 1 < \left\lfloor \log_2 x \right\rfloor \leqslant \log_2 x
$$
thus
$$
2^{\log_2 x - 1} < 2^{\left\lfloor \log_2 x \right\rfloor} \leqslant 2^{\log_2 x}
$$
then
$$
\frac{x}{2} < 2^{\left\lfloor \log_2 x \right\rfloor} \leqslant x
$$
and finally:
$$
\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}} \in [1;2)
$$
Let's pick $\alpha$ such that
$$
\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}} = \frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}} \cdot (1 - \alpha)
$$
$$
\alpha = \frac{\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}} - \left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}}{\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}} \in \left[0; 2^{-127}\right)
$$
Let's pick $\beta$ such that
$$
\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}} = \left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2 \cdot (1 - \beta)
$$
$$
\beta = \frac{\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2 - \left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}}{\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2} \in \left[0; 2^{-127}\right)
$$
Now we have:
$$
\varepsilon_{i+1}(x) = \dots =\\=
\frac{1}{2} \left(l_i \left(\left(\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\cdot (1 - \alpha)\right)^2 \cdot (1 - \beta)\right) - \log_2\left(\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right)^2\right) =\\=
\frac{1}{2} \left(l_i \left(\left(\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right)^2 \cdot (1 - \alpha)^2 \cdot (1 - \beta)\right) -\\- \log_2\left(\left(\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right)^2 \cdot (1 - \alpha)^2 \cdot (1 - \beta)\right) +\\+
\log_2 \left((1 - \alpha)^2 \cdot (1 - \beta)\right)\right)=\\=
\frac{1}{2}\left(\varepsilon_i\left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) + \log_2 \left((1 - \alpha)^2 \cdot (1 - \beta)\right)\right) =\\=
\frac{1}{2}\left(\varepsilon_i\left(\left\lfloor\left(\left\lfloor\frac{x}{2^{\left\lfloor \log_2 x \right\rfloor}}\right\rfloor_{2^{-127}}\right)^2\right\rfloor_{2^{-127}}\right) + 2 \log_2 \left(1 - \alpha\right) + \log_2 \left(1 - \beta\right)\right) \in\\\in
\left(\frac{1}{2} \min \varepsilon_i + \frac{3}{2} \log_2\left(1 - 2^{-127}\right);+0\right] =\\=
\left(-\,2^{-(i + 1)} + 3\left(1-2^{-(i + 1)}\right)\log_2\left(1 - 2^{-127}\right);0\right]
$$
## Base-1.01 Logarithm Approximation
We approximate base-1.01 logarithm $\log_{1.01} x$ like this:
$$
\log_{1.01} x \approx \xi \cdot l_i (x)
$$
Where $\xi = \frac{1285013416526911433821}{2^{64}} > \frac{1}{\log_2 1.01}$. The error of such approximation is:
$$
\xi \cdot l_i (x) - \log_{1.01} x =\\=
\xi \cdot \left(\log_2 x + \varepsilon_i (x)\right) - \frac{\log_2 x}{\log_2 1.01} =\\=
\log_2 x\left(\xi - \frac{1}{\log_2 1.01}\right) + \xi \cdot \varepsilon_i (x)
$$
For $x \in \left[2^{-112}; 2^{112}\right)$ the approximation error is within the following range:
$$
\left(-112\left(\xi - \frac{1}{\log_2 1.01}\right) + \xi \cdot \left(-\,2^{-i} + 3\left(1-2^{-i}\right)\log_2\left(1 - 2^{-127}\right)\right);\\
112\left(\xi - \frac{1}{\log_2 1.01}\right)\right)
$$
## Base-$\sqrt{1.0001}$ Logarithm Approximation
We approximate base-$\sqrt{1.0001}$ logarithm $\log_{\sqrt{1.0001}} x$ like this:
$$
\log_{\sqrt{1.0001}} x \approx \psi \cdot l_i (x)
$$
Where $\psi = \frac{255738958999603826347141}{2^{64}} > \frac{1}{\log_2 \sqrt{1.0001}}$. The error of such approximation is:
$$
\psi \cdot l_i (x) - \log_{\sqrt{1.0001}} x =\\=
\psi \cdot \left(\log_2 x + \varepsilon_i (x)\right) - \frac{\log_2 x}{\log_2 \sqrt{1.0001}} =\\=
\log_2 x\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right) + \psi \cdot \varepsilon_i (x)
$$
For $x \in \left[2^{-64}; 2^{64}\right)$ the approximation error is within the following range:
$$
\left(-64\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right) + \psi \cdot \left(-\,2^{-i} + 3\left(1-2^{-i}\right)\log_2\left(1 - 2^{-127}\right)\right);\\
64\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right)\right)
$$
## Approximation of $\mathtt{getRatioAtTick}^{-1}$ (normal ticks)
Function $\mathtt{getRatioAtTick}(x)$ approximates $1.01^x$ with relative pricision not worse than $0.01\%$. Thus:
$$
\mathtt{getRatioAtTick} (x) = \gamma(x) \cdot 1.01^x
$$
where $\gamma(x) \in \left[0.9999; 1.0001\right]$. By inverting this function we have:
$$
\mathtt{getRatioAtTick}^{-1} (x) = \log_{1.01} \frac{x}{\gamma(y)} = \log_{1.01} x - \log_{1.01} \gamma(y)
$$
Here $y$ is some number. Note, that while actual $\mathtt{getRatioAtTick}(x)$ function may be calculated only for integer arguments, we assume that it is consinuously and strictly-monotonically defined for all real numbers. This assumtion allows us to consider inverse function $\mathtt{getRatioAtTick}^{-1} (x)$ to be defined for all positive arguments.
We approximate the inverse function $\mathtt{getRatioAtTick}^{-1} (x)$ like this:
$$
\log_{1.01} x - \log_{1.01} \gamma(y) \approx \xi \cdot l_i (x)
$$
The absoulte error of such approximation is:
$$
\xi \cdot l_i (x) - \log_{1.01} x + \log_{1.01} \gamma(y)
$$
For $x \in \left[2^{-112}; 2^{112}\right)$ the error is within the following range:
$$
\left(-112\left(\xi - \frac{1}{\log_2 1.01}\right) +\\+
\,\xi \cdot \left(-\,2^{-i} + 3\left(1-2^{-i}\right)\log_2\left(1 - 2^{-127}\right)\right) +\\+
\log_{1.01} 0.9999;\\
112\left(\xi - \frac{1}{\log_2 1.01}\right) + \log_{1.01} 1.0001\right)
$$
Here $-112\left(\xi - \frac{1}{\log_2 1.01}\right)$ and $112\left(\xi - \frac{1}{\log_2 1.01}\right)$ are contributed by the imperfection of $\xi$ value; $\xi \cdot \left(-\,2^{-i}\right)$ is contributed by the finity of $i$; $\xi \cdot 3\left(1-2^{-i}\right)\log_2\left(1 - 2^{-127}\right)$ is contributed by the rounding errors inside the approximation algorithm implementation (the implementation uses 129.127-bit binary fixed point numbers, thus $2^{-127}$ thing); finally $\log_{1.01} 0.9999$ and $\log_{1.01} 1.0001$ are contributed by the imperfection of $\mathtt{getRatioAtTick}$ implementation.
## Approximation of $\mathtt{getRatioAtTick}^{-1}$ (fine ticks)
Function $\mathtt{getRatioAtTick}(x)$ approximates $\sqrt{1.0001}^x$ with relative pricision not worse than $0.00005\%$. Thus:
$$
\mathtt{getRatioAtTick} (x) = \gamma(x) \cdot \sqrt{1.0001}^x
$$
where $\gamma(x) \in \left[0.9999995; 1.0000005\right]$. By inverting this function we have:
$$
\mathtt{getRatioAtTick}^{-1} (x) = \log_{\sqrt{1.0001}} \frac{x}{\gamma(y)} = \log_{\sqrt{1.0001}} x - \log_{\sqrt{1.0001}} \gamma(y)
$$
Here $y$ is some number. Note, that while actual $\mathtt{getRatioAtTick}(x)$ function may be calculated only for integer arguments, we assume that it is consinuously and strictly-monotonically defined for all real numbers. This assumtion allows us to consider inverse function $\mathtt{getRatioAtTick}^{-1} (x)$ to be defined for all positive arguments.
We approximate the inverse function $\mathtt{getRatioAtTick}^{-1} (x)$ like this:
$$
\log_{\sqrt{1.0001}} x - \log_{\sqrt{1.0001}} \gamma(y) \approx \psi \cdot l_i (x)
$$
The absoulte error of such approximation is:
$$
\psi \cdot l_i (x) - \log_{\sqrt{1.0001}} x + \log_{\sqrt{1.0001}} \gamma(y)
$$
For $x \in \left[2^{-64}; 2^{64}\right)$ the error is within the following range:
$$
\left(-64\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right) +\\+
\,\psi \cdot \left(-\,2^{-i} + 3\left(1-2^{-i}\right)\log_2\left(1 - 2^{-127}\right)\right) +\\+
\log_{\sqrt{1.0001}} 0.9999995;\\
64\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right) + \log_{\sqrt{1.0001}} 1.0000005\right)
$$
Here $-64\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right)$ and $64\left(\psi - \frac{1}{\log_2 \sqrt{1.0001}}\right)$ are contributed by the imperfection of $\psi$ value; $\psi \cdot \left(-\,2^{-i}\right)$ is contributed by the finity of $i$; $\psi \cdot 3\left(1-2^{-i}\right)\log_2\left(1 - 2^{-127}\right)$ is contributed by the rounding errors inside the approximation algorithm implementation (the implementation uses 129.127-bit binary fixed point numbers, thus $2^{-127}$ thing); finally $\log_{\sqrt{1.0001}} 0.9999995$ and $\log_{\sqrt{1.0001}} 1.0000005$ are contributed by the imperfection of $\mathtt{getRatioAtTick}$ implementation.
## Choosing The Right $i$ (normal ticks)
What we need is to calculate for given positive value $y$ the maximum integer $x$ such that $\mathtt{getRatioAtTick}(x) \leqslant y$. Basically we need to solve the following inequation in integer numbers:
$$
\mathtt{getRatioAtTick}(x) \leqslant y < \mathtt{getRatioAtTick}(x + 1)
$$
or
$$
x \leqslant \mathtt{getRatioAtTick}^{-1}(y) < x + 1
$$
Thus:
$$
x = \left\lfloor\mathtt{getRatioAtTick}^{-1}(y)\right\rfloor
$$
Once we know, that $\mathtt{getRatioAtTick}^{-1}(y) \in \left[x_{min};x_{max}\right]$, then $x \in \left[\left\lfloor x_{min}\right\rfloor; \left\lfloor x_{max}\right\rfloor\right]$. When $x_{max} - x_{min} < 1$ there are at most two integer values fitting into range $\left[\left\lfloor x_{min}\right\rfloor; \left\lfloor x_{max}\right\rfloor\right]$, thus the right value could be chosen by calling $\mathtt{getRatioAtTick}$ function at most once.
The following table gives possible ranges of absolute approximation error $\varepsilon$ of $\mathtt{getRatioAtTick}^{-1}(y)$ for $i \in \{0, \dots, 10\}$:
| $i$ | $\min \varepsilon$ | $\max \varepsilon$ | $P$ |
| ---- | ------------------ | ------------------ | --- |
| $0$ | $-69.68$ | $0.01005$ | |
| $1$ | $-34.85$ | $0.01005$ | |
| $2$ | $-17.43$ | $0.01005$ | |
| $3$ | $-8.718$ | $0.01005$ | |
| $4$ | $-4.364$ | $0.01005$ | |
| $5$ | $-2.187$ | $0.01005$ | |
| $6$ | $-1.099$ | $0.01005$ | |
| $7$ | $-0.5543$ | $0.01005$ | $57\%$ |
| $8$ | $-0.2822$ | $0.01005$ | $30\%$ |
| $9$ | $-0.1462$ | $0.01005$ | $16\%$ |
| $10$ | $-0.07808$ | $0.01005$ | $9\%$ |
For $i \geqslant 7$ at most one call to $\mathrm{getRatioAtTick}$ is needed to return bit-perfect $\mathrm{getRatioAtTick}^{-1} x$ value. The probability $P$ of $\mathrm{getRatioAtTick}$ call is shown in the last column.
## Choosing The Right $i$ (fine ticks)
What we need is to calculate for given positive value $y$ the maximum integer $x$ such that $\mathtt{getRatioAtTick}(x) \leqslant y$. Basically we need to solve the following inequation in integer numbers:
$$
\mathtt{getRatioAtTick}(x) \leqslant y < \mathtt{getRatioAtTick}(x + 1)
$$
or
$$
x \leqslant \mathtt{getRatioAtTick}^{-1}(y) < x + 1
$$
Thus:
$$
x = \left\lfloor\mathtt{getRatioAtTick}^{-1}(y)\right\rfloor
$$
Once we know, that $\mathtt{getRatioAtTick}^{-1}(y) \in \left[x_{min};x_{max}\right]$, then $x \in \left[\left\lfloor x_{min}\right\rfloor; \left\lfloor x_{max}\right\rfloor\right]$. When $x_{max} - x_{min} < 1$ there are at most two integer values fitting into range $\left[\left\lfloor x_{min}\right\rfloor; \left\lfloor x_{max}\right\rfloor\right]$, thus the right value could be chosen by calling $\mathtt{getRatioAtTick}$ function at most once.
The following table gives possible ranges of absolute approximation error $\varepsilon$ of $\mathtt{getRatioAtTick}^{-1}(y)$ for $i \in \{0, \dots, 20\}$:
| $i$ | $\min \varepsilon$ | $\max \varepsilon$ | $P$ |
| ---- | ------------------ | ------------------ | --- |
| $0$ | $-13863.6$ | $0.0100005$ | |
| $1$ | $-6931.83$ | $0.0100005$ | |
| $2$ | $-3465.92$ | $0.0100005$ | |
| $3$ | $-1732.96$ | $0.0100005$ | |
| $4$ | $-866.487$ | $0.0100005$ | |
| $5$ | $-433.249$ | $0.0100005$ | |
| $6$ | $-216.629$ | $0.0100005$ | |
| $7$ | $-108.32$ | $0.0100005$ | |
| $8$ | $-54.1648$ | $0.0100005$ | |
| $9$ | $-27.0874$ | $0.0100005$ | |
| $10$ | $-13.5487$ | $0.0100005$ | |
| $11$ | $-6.77935$ | $0.0100005$ | |
| $12$ | $-3.39468$ | $0.0100005$ | |
| $13$ | $-1.70234$ | $0.0100005$ | |
| $14$ | $-0.85617$ | $0.0100005$ | 86% |
| $15$ | $-0.433085$ | $0.0100005$ | 44% |
| $16$ | $-0.221543$ | $0.0100005$ | 23% |
| $17$ | $-0.115772$ | $0.0100005$ | 12% |
| $18$ | $-0.0628861$ | $0.0100005$ | 7% |
| $19$ | $-0.0364433$ | $0.0100005$ | 4% |
| $20$ | $-0.0232219$ | $0.0100005$ | 3% |
For $i \geqslant 14$ at most one call to $\mathrm{getRatioAtTick}$ is needed to return bit-perfect $\mathrm{getRatioAtTick}^{-1} x$ value. The probability $P$ of $\mathrm{getRatioAtTick}$ call is shown in the last column.