Average Error: 3.7 → 0.3
Time: 22.8s
Precision: 64
\[x \cdot \left(1 - \left(1 - y\right) \cdot z\right)\]
\[\begin{array}{l} \mathbf{if}\;z \le -9.65927490258674399 \cdot 10^{-44} \lor \neg \left(z \le 6.8158029305576074 \cdot 10^{-126}\right):\\ \;\;\;\;\mathsf{fma}\left(x, 1, \left(x \cdot z\right) \cdot \left(y - 1\right)\right)\\ \mathbf{else}:\\ \;\;\;\;\mathsf{fma}\left(z, y - 1, 1\right) \cdot x\\ \end{array}\]
x \cdot \left(1 - \left(1 - y\right) \cdot z\right)
\begin{array}{l}
\mathbf{if}\;z \le -9.65927490258674399 \cdot 10^{-44} \lor \neg \left(z \le 6.8158029305576074 \cdot 10^{-126}\right):\\
\;\;\;\;\mathsf{fma}\left(x, 1, \left(x \cdot z\right) \cdot \left(y - 1\right)\right)\\

\mathbf{else}:\\
\;\;\;\;\mathsf{fma}\left(z, y - 1, 1\right) \cdot x\\

\end{array}
double f(double x, double y, double z) {
        double r515891 = x;
        double r515892 = 1.0;
        double r515893 = y;
        double r515894 = r515892 - r515893;
        double r515895 = z;
        double r515896 = r515894 * r515895;
        double r515897 = r515892 - r515896;
        double r515898 = r515891 * r515897;
        return r515898;
}

double f(double x, double y, double z) {
        double r515899 = z;
        double r515900 = -9.659274902586744e-44;
        bool r515901 = r515899 <= r515900;
        double r515902 = 6.815802930557607e-126;
        bool r515903 = r515899 <= r515902;
        double r515904 = !r515903;
        bool r515905 = r515901 || r515904;
        double r515906 = x;
        double r515907 = 1.0;
        double r515908 = r515906 * r515899;
        double r515909 = y;
        double r515910 = r515909 - r515907;
        double r515911 = r515908 * r515910;
        double r515912 = fma(r515906, r515907, r515911);
        double r515913 = fma(r515899, r515910, r515907);
        double r515914 = r515913 * r515906;
        double r515915 = r515905 ? r515912 : r515914;
        return r515915;
}

Error

Bits error versus x

Bits error versus y

Bits error versus z

Target

Original3.7
Target0.3
Herbie0.3
\[\begin{array}{l} \mathbf{if}\;x \cdot \left(1 - \left(1 - y\right) \cdot z\right) \lt -1.618195973607049 \cdot 10^{50}:\\ \;\;\;\;x + \left(1 - y\right) \cdot \left(\left(-z\right) \cdot x\right)\\ \mathbf{elif}\;x \cdot \left(1 - \left(1 - y\right) \cdot z\right) \lt 3.8922376496639029 \cdot 10^{134}:\\ \;\;\;\;\left(x \cdot y\right) \cdot z - \left(x \cdot z - x\right)\\ \mathbf{else}:\\ \;\;\;\;x + \left(1 - y\right) \cdot \left(\left(-z\right) \cdot x\right)\\ \end{array}\]

Derivation

  1. Split input into 2 regimes
  2. if z < -9.659274902586744e-44 or 6.815802930557607e-126 < z

    1. Initial program 6.7

      \[x \cdot \left(1 - \left(1 - y\right) \cdot z\right)\]
    2. Simplified6.7

      \[\leadsto \color{blue}{\mathsf{fma}\left(z, y - 1, 1\right) \cdot x}\]
    3. Taylor expanded around inf 6.7

      \[\leadsto \color{blue}{\left(1 \cdot x + x \cdot \left(z \cdot y\right)\right) - 1 \cdot \left(x \cdot z\right)}\]
    4. Simplified0.6

      \[\leadsto \color{blue}{\mathsf{fma}\left(x, 1, \left(x \cdot z\right) \cdot \left(y - 1\right)\right)}\]

    if -9.659274902586744e-44 < z < 6.815802930557607e-126

    1. Initial program 0.1

      \[x \cdot \left(1 - \left(1 - y\right) \cdot z\right)\]
    2. Simplified0.1

      \[\leadsto \color{blue}{\mathsf{fma}\left(z, y - 1, 1\right) \cdot x}\]
  3. Recombined 2 regimes into one program.
  4. Final simplification0.3

    \[\leadsto \begin{array}{l} \mathbf{if}\;z \le -9.65927490258674399 \cdot 10^{-44} \lor \neg \left(z \le 6.8158029305576074 \cdot 10^{-126}\right):\\ \;\;\;\;\mathsf{fma}\left(x, 1, \left(x \cdot z\right) \cdot \left(y - 1\right)\right)\\ \mathbf{else}:\\ \;\;\;\;\mathsf{fma}\left(z, y - 1, 1\right) \cdot x\\ \end{array}\]

Reproduce

herbie shell --seed 2019199 +o rules:numerics
(FPCore (x y z)
  :name "Data.Colour.RGBSpace.HSV:hsv from colour-2.3.3, J"

  :herbie-target
  (if (< (* x (- 1.0 (* (- 1.0 y) z))) -1.618195973607049e+50) (+ x (* (- 1.0 y) (* (- z) x))) (if (< (* x (- 1.0 (* (- 1.0 y) z))) 3.892237649663903e+134) (- (* (* x y) z) (- (* x z) x)) (+ x (* (- 1.0 y) (* (- z) x)))))

  (* x (- 1.0 (* (- 1.0 y) z))))