求 log 近似值

使用 \(\tanh^{-1}x\) 的泰勒展開來解釋

觀察 kxo 作業說明fixed_log 的實作:

Q23_8 fixed_log(int input)
{
    if (!input || input == (1U << Q))
        return 0;

    int64_t y = input << Q;
    y = ((y - (1U << Q)) << (Q)) / (y + (1U << Q));
    int64_t ans = 0U;
    for (unsigned i = 1; i < 20; i += 2) {
        int64_t z = (1U << Q);
        for (int j = 0; j < i; j++) {
            z *= y;
            z >>= Q;
        }
        z <<= Q;
        z /= (i << Q);

        ans += z;
    }
    ans <<= 1;
    return (Q23_8) ans;
}

以下以再不考慮定點數的觀點來看這個實作的數學部份:
它是在求 \(\displaystyle 2\sum_{i=0}^{\infty}\frac{1}{2i+1}(\frac{y-1}{y+1})^{2i+1}\)
會發現,\(\displaystyle \tanh^{-1}x = \sum_{i=0}^{\infty}\frac{1}{2i+1}x^{2i+1}\),然後我們把上式帶入:

\(\displaystyle 2\sum_{i=0}^{\infty}\frac{1}{2i+1}(\frac{y-1}{y+1})^{2i+1} = 2\tanh^{-1}(\frac{y-1}{y+1})\)

\(\displaystyle \text{Let } x = \frac{y-1}{y+1},\ k=2\tanh^{-1}x\)

\(\displaystyle \Rightarrow \tanh\frac{k}{2}=x\)

\(\displaystyle \Rightarrow x=\frac{e^{k}-1}{e^k+1}\)

\(\displaystyle \Rightarrow e^kx+x=e^k-1\)

\(\displaystyle \Rightarrow e^k=\frac{1+x}{1-x} = \frac{1+\frac{y-1}{y+1}}{1-\frac{y-1}{y+1}}=y\)

\(\displaystyle k=\ln y\)

所以,實際上這個函數是使用 \(\tanh^{-1}\) 來估計 \(\ln\)

使用 \(\ln\) 的泰勒展開式來解釋

\(\displaystyle 2\sum_{i=0}^{\infty}\frac{1}{2i+1}(\frac{y-1}{y+1})^{2i+1}\)

\(\displaystyle \sum_{i=1}^{\infty}\frac{1}{i}(\frac{y-1}{y+1})^i - \sum_{i=1}^{\infty}\frac{1}{i}(-\frac{y-1}{y+1})^i\)

\(\displaystyle = \ln(1+\frac{y-1}{y+1}) - \ln(1-\frac{y-1}{y+1})\)

\(\displaystyle = \ln(2y) - \ln2\)

\(\displaystyle = \ln y\)