Average Error: 39.1 → 0.5
Time: 10.9s
Precision: 64
\[\log \left(1 + x\right)\]
\[\begin{array}{l} \mathbf{if}\;x + 1 \le 1:\\ \;\;\;\;\mathsf{fma}\left(x, 1, \mathsf{fma}\left(\frac{x \cdot x}{1 \cdot 1}, \frac{1}{2}, \frac{\frac{x \cdot \left(x \cdot x\right)}{1 \cdot 1}}{1} \cdot \frac{1}{3}\right)\right) - \left(x \cdot x\right) \cdot 1\\ \mathbf{else}:\\ \;\;\;\;\log \left(\sqrt{x + 1}\right) + \log \left(\sqrt{x + 1}\right)\\ \end{array}\]
\log \left(1 + x\right)
\begin{array}{l}
\mathbf{if}\;x + 1 \le 1:\\
\;\;\;\;\mathsf{fma}\left(x, 1, \mathsf{fma}\left(\frac{x \cdot x}{1 \cdot 1}, \frac{1}{2}, \frac{\frac{x \cdot \left(x \cdot x\right)}{1 \cdot 1}}{1} \cdot \frac{1}{3}\right)\right) - \left(x \cdot x\right) \cdot 1\\

\mathbf{else}:\\
\;\;\;\;\log \left(\sqrt{x + 1}\right) + \log \left(\sqrt{x + 1}\right)\\

\end{array}
double f(double x) {
        double r3043198 = 1.0;
        double r3043199 = x;
        double r3043200 = r3043198 + r3043199;
        double r3043201 = log(r3043200);
        return r3043201;
}

double f(double x) {
        double r3043202 = x;
        double r3043203 = 1.0;
        double r3043204 = r3043202 + r3043203;
        bool r3043205 = r3043204 <= r3043203;
        double r3043206 = r3043202 * r3043202;
        double r3043207 = r3043203 * r3043203;
        double r3043208 = r3043206 / r3043207;
        double r3043209 = 0.5;
        double r3043210 = r3043202 * r3043206;
        double r3043211 = r3043210 / r3043207;
        double r3043212 = r3043211 / r3043203;
        double r3043213 = 0.3333333333333333;
        double r3043214 = r3043212 * r3043213;
        double r3043215 = fma(r3043208, r3043209, r3043214);
        double r3043216 = fma(r3043202, r3043203, r3043215);
        double r3043217 = r3043206 * r3043203;
        double r3043218 = r3043216 - r3043217;
        double r3043219 = sqrt(r3043204);
        double r3043220 = log(r3043219);
        double r3043221 = r3043220 + r3043220;
        double r3043222 = r3043205 ? r3043218 : r3043221;
        return r3043222;
}

Error

Bits error versus x

Target

Original39.1
Target0.3
Herbie0.5
\[\begin{array}{l} \mathbf{if}\;1 + x = 1:\\ \;\;\;\;x\\ \mathbf{else}:\\ \;\;\;\;\frac{x \cdot \log \left(1 + x\right)}{\left(1 + x\right) - 1}\\ \end{array}\]

Derivation

  1. Split input into 2 regimes
  2. if (+ 1.0 x) < 1.0

    1. Initial program 59.5

      \[\log \left(1 + x\right)\]
    2. Using strategy rm
    3. Applied flip-+59.5

      \[\leadsto \log \color{blue}{\left(\frac{1 \cdot 1 - x \cdot x}{1 - x}\right)}\]
    4. Applied log-div59.5

      \[\leadsto \color{blue}{\log \left(1 \cdot 1 - x \cdot x\right) - \log \left(1 - x\right)}\]
    5. Simplified59.5

      \[\leadsto \color{blue}{\log \left(\left(x + 1\right) \cdot \left(1 - x\right)\right)} - \log \left(1 - x\right)\]
    6. Taylor expanded around 0 0.2

      \[\leadsto \color{blue}{\left(1 \cdot x + \left(\frac{1}{3} \cdot \frac{{x}^{3}}{{1}^{3}} + \frac{1}{2} \cdot \frac{{x}^{2}}{{1}^{2}}\right)\right) - 1 \cdot {x}^{2}}\]
    7. Simplified0.2

      \[\leadsto \color{blue}{\mathsf{fma}\left(x, 1, \mathsf{fma}\left(\frac{x \cdot x}{1 \cdot 1}, \frac{1}{2}, \frac{1}{3} \cdot \frac{\frac{\left(x \cdot x\right) \cdot x}{1 \cdot 1}}{1}\right)\right) - \left(x \cdot x\right) \cdot 1}\]

    if 1.0 < (+ 1.0 x)

    1. Initial program 0.9

      \[\log \left(1 + x\right)\]
    2. Using strategy rm
    3. Applied add-sqr-sqrt1.0

      \[\leadsto \log \color{blue}{\left(\sqrt{1 + x} \cdot \sqrt{1 + x}\right)}\]
    4. Applied log-prod1.0

      \[\leadsto \color{blue}{\log \left(\sqrt{1 + x}\right) + \log \left(\sqrt{1 + x}\right)}\]
  3. Recombined 2 regimes into one program.
  4. Final simplification0.5

    \[\leadsto \begin{array}{l} \mathbf{if}\;x + 1 \le 1:\\ \;\;\;\;\mathsf{fma}\left(x, 1, \mathsf{fma}\left(\frac{x \cdot x}{1 \cdot 1}, \frac{1}{2}, \frac{\frac{x \cdot \left(x \cdot x\right)}{1 \cdot 1}}{1} \cdot \frac{1}{3}\right)\right) - \left(x \cdot x\right) \cdot 1\\ \mathbf{else}:\\ \;\;\;\;\log \left(\sqrt{x + 1}\right) + \log \left(\sqrt{x + 1}\right)\\ \end{array}\]

Reproduce

herbie shell --seed 2019171 +o rules:numerics
(FPCore (x)
  :name "ln(1 + x)"

  :herbie-target
  (if (== (+ 1.0 x) 1.0) x (/ (* x (log (+ 1.0 x))) (- (+ 1.0 x) 1.0)))

  (log (+ 1.0 x)))