觀察 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\)
\(\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\)