
(FPCore (x) :precision binary64 (asinh x))
double code(double x) {
return asinh(x);
}
def code(x): return math.asinh(x)
function code(x) return asinh(x) end
function tmp = code(x) tmp = asinh(x); end
code[x_] := N[ArcSinh[x], $MachinePrecision]
\begin{array}{l}
\\
\sinh^{-1} x
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 2 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x) :precision binary64 (copysign (log (+ (fabs x) (sqrt (+ (* x x) 1.0)))) x))
double code(double x) {
return copysign(log((fabs(x) + sqrt(((x * x) + 1.0)))), x);
}
public static double code(double x) {
return Math.copySign(Math.log((Math.abs(x) + Math.sqrt(((x * x) + 1.0)))), x);
}
def code(x): return math.copysign(math.log((math.fabs(x) + math.sqrt(((x * x) + 1.0)))), x)
function code(x) return copysign(log(Float64(abs(x) + sqrt(Float64(Float64(x * x) + 1.0)))), x) end
function tmp = code(x) tmp = sign(x) * abs(log((abs(x) + sqrt(((x * x) + 1.0))))); end
code[x_] := N[With[{TMP1 = Abs[N[Log[N[(N[Abs[x], $MachinePrecision] + N[Sqrt[N[(N[(x * x), $MachinePrecision] + 1.0), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]], $MachinePrecision]], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
\begin{array}{l}
\\
\mathsf{copysign}\left(\log \left(\left|x\right| + \sqrt{x \cdot x + 1}\right), x\right)
\end{array}
(FPCore (x) :precision binary64 (copysign (asinh x) x))
double code(double x) {
return copysign(asinh(x), x);
}
def code(x): return math.copysign(math.asinh(x), x)
function code(x) return copysign(asinh(x), x) end
function tmp = code(x) tmp = sign(x) * abs(asinh(x)); end
code[x_] := N[With[{TMP1 = Abs[N[ArcSinh[x], $MachinePrecision]], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
\begin{array}{l}
\\
\mathsf{copysign}\left(\sinh^{-1} x, x\right)
\end{array}
Initial program 31.8%
lift-log.f64N/A
lift-+.f64N/A
lift-fabs.f64N/A
lift-sqrt.f64N/A
lift-+.f64N/A
lift-*.f64N/A
pow2N/A
+-commutativeN/A
+-commutativeN/A
pow2N/A
sqr-abs-revN/A
asinh-def-revN/A
rem-sqrt-square-revN/A
pow2N/A
sqrt-pow1N/A
metadata-evalN/A
unpow1N/A
lower-asinh.f6499.8
Applied rewrites99.8%
(FPCore (x)
:precision binary64
(let* ((t_0 (pow (+ 1.0 x) 2.0))
(t_1 (pow t_0 -1.0))
(t_2 (pow (+ 1.0 x) -1.0)))
(copysign
(fma
(fma
(fma
(* 0.001388888888888889 (* x x))
(fma 45.0 t_2 (fma 45.0 t_1 (/ 30.0 (pow t_0 1.5))))
(* (fma t_1 3.0 (* t_2 3.0)) -0.041666666666666664))
(* x x)
(* t_2 0.5))
(* x x)
(log1p x))
x)))
double code(double x) {
double t_0 = pow((1.0 + x), 2.0);
double t_1 = pow(t_0, -1.0);
double t_2 = pow((1.0 + x), -1.0);
return copysign(fma(fma(fma((0.001388888888888889 * (x * x)), fma(45.0, t_2, fma(45.0, t_1, (30.0 / pow(t_0, 1.5)))), (fma(t_1, 3.0, (t_2 * 3.0)) * -0.041666666666666664)), (x * x), (t_2 * 0.5)), (x * x), log1p(x)), x);
}
function code(x) t_0 = Float64(1.0 + x) ^ 2.0 t_1 = t_0 ^ -1.0 t_2 = Float64(1.0 + x) ^ -1.0 return copysign(fma(fma(fma(Float64(0.001388888888888889 * Float64(x * x)), fma(45.0, t_2, fma(45.0, t_1, Float64(30.0 / (t_0 ^ 1.5)))), Float64(fma(t_1, 3.0, Float64(t_2 * 3.0)) * -0.041666666666666664)), Float64(x * x), Float64(t_2 * 0.5)), Float64(x * x), log1p(x)), x) end
code[x_] := Block[{t$95$0 = N[Power[N[(1.0 + x), $MachinePrecision], 2.0], $MachinePrecision]}, Block[{t$95$1 = N[Power[t$95$0, -1.0], $MachinePrecision]}, Block[{t$95$2 = N[Power[N[(1.0 + x), $MachinePrecision], -1.0], $MachinePrecision]}, N[With[{TMP1 = Abs[N[(N[(N[(N[(0.001388888888888889 * N[(x * x), $MachinePrecision]), $MachinePrecision] * N[(45.0 * t$95$2 + N[(45.0 * t$95$1 + N[(30.0 / N[Power[t$95$0, 1.5], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(N[(t$95$1 * 3.0 + N[(t$95$2 * 3.0), $MachinePrecision]), $MachinePrecision] * -0.041666666666666664), $MachinePrecision]), $MachinePrecision] * N[(x * x), $MachinePrecision] + N[(t$95$2 * 0.5), $MachinePrecision]), $MachinePrecision] * N[(x * x), $MachinePrecision] + N[Log[1 + x], $MachinePrecision]), $MachinePrecision]], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := {\left(1 + x\right)}^{2}\\
t_1 := {t\_0}^{-1}\\
t_2 := {\left(1 + x\right)}^{-1}\\
\mathsf{copysign}\left(\mathsf{fma}\left(\mathsf{fma}\left(\mathsf{fma}\left(0.001388888888888889 \cdot \left(x \cdot x\right), \mathsf{fma}\left(45, t\_2, \mathsf{fma}\left(45, t\_1, \frac{30}{{t\_0}^{1.5}}\right)\right), \mathsf{fma}\left(t\_1, 3, t\_2 \cdot 3\right) \cdot -0.041666666666666664\right), x \cdot x, t\_2 \cdot 0.5\right), x \cdot x, \mathsf{log1p}\left(x\right)\right), x\right)
\end{array}
\end{array}
Initial program 31.8%
Taylor expanded in x around 0
Applied rewrites50.5%
herbie shell --seed 2025065
(FPCore (x)
:name "Rust f64::asinh"
:precision binary64
:alt
(! :herbie-platform c (let* ((ax (fabs x)) (ix (/ 1 ax))) (copysign (log1p (+ ax (/ ax (+ (hypot 1 ix) ix)))) x)))
(copysign (log (+ (fabs x) (sqrt (+ (* x x) 1.0)))) x))