(FPCore (a b c d)
:precision binary64
(/ (- (* b c) (* a d)) (+ (* c c) (* d d))))
↓
(FPCore (a b c d)
:precision binary64
(let* ((t_0 (* (/ 1.0 (hypot c d)) (/ (- (* c b) (* d a)) (hypot c d))))
(t_1 (- (/ b c) (* (/ d c) (/ a c)))))
(if (<= c -5.5e+88)
t_1
(if (<= c -6.2e-71)
t_0
(if (<= c 2.2e-60)
(/ (- (/ (* c b) d) a) d)
(if (<= c 1.55e+130) t_0 t_1))))))
double code(double a, double b, double c, double d) {
return ((b * c) - (a * d)) / ((c * c) + (d * d));
}
↓
double code(double a, double b, double c, double d) {
double t_0 = (1.0 / hypot(c, d)) * (((c * b) - (d * a)) / hypot(c, d));
double t_1 = (b / c) - ((d / c) * (a / c));
double tmp;
if (c <= -5.5e+88) {
tmp = t_1;
} else if (c <= -6.2e-71) {
tmp = t_0;
} else if (c <= 2.2e-60) {
tmp = (((c * b) / d) - a) / d;
} else if (c <= 1.55e+130) {
tmp = t_0;
} else {
tmp = t_1;
}
return tmp;
}
public static double code(double a, double b, double c, double d) {
return ((b * c) - (a * d)) / ((c * c) + (d * d));
}
↓
public static double code(double a, double b, double c, double d) {
double t_0 = (1.0 / Math.hypot(c, d)) * (((c * b) - (d * a)) / Math.hypot(c, d));
double t_1 = (b / c) - ((d / c) * (a / c));
double tmp;
if (c <= -5.5e+88) {
tmp = t_1;
} else if (c <= -6.2e-71) {
tmp = t_0;
} else if (c <= 2.2e-60) {
tmp = (((c * b) / d) - a) / d;
} else if (c <= 1.55e+130) {
tmp = t_0;
} else {
tmp = t_1;
}
return tmp;
}
def code(a, b, c, d):
return ((b * c) - (a * d)) / ((c * c) + (d * d))
↓
def code(a, b, c, d):
t_0 = (1.0 / math.hypot(c, d)) * (((c * b) - (d * a)) / math.hypot(c, d))
t_1 = (b / c) - ((d / c) * (a / c))
tmp = 0
if c <= -5.5e+88:
tmp = t_1
elif c <= -6.2e-71:
tmp = t_0
elif c <= 2.2e-60:
tmp = (((c * b) / d) - a) / d
elif c <= 1.55e+130:
tmp = t_0
else:
tmp = t_1
return tmp
function code(a, b, c, d)
return Float64(Float64(Float64(b * c) - Float64(a * d)) / Float64(Float64(c * c) + Float64(d * d)))
end
↓
function code(a, b, c, d)
t_0 = Float64(Float64(1.0 / hypot(c, d)) * Float64(Float64(Float64(c * b) - Float64(d * a)) / hypot(c, d)))
t_1 = Float64(Float64(b / c) - Float64(Float64(d / c) * Float64(a / c)))
tmp = 0.0
if (c <= -5.5e+88)
tmp = t_1;
elseif (c <= -6.2e-71)
tmp = t_0;
elseif (c <= 2.2e-60)
tmp = Float64(Float64(Float64(Float64(c * b) / d) - a) / d);
elseif (c <= 1.55e+130)
tmp = t_0;
else
tmp = t_1;
end
return tmp
end
function tmp = code(a, b, c, d)
tmp = ((b * c) - (a * d)) / ((c * c) + (d * d));
end
↓
function tmp_2 = code(a, b, c, d)
t_0 = (1.0 / hypot(c, d)) * (((c * b) - (d * a)) / hypot(c, d));
t_1 = (b / c) - ((d / c) * (a / c));
tmp = 0.0;
if (c <= -5.5e+88)
tmp = t_1;
elseif (c <= -6.2e-71)
tmp = t_0;
elseif (c <= 2.2e-60)
tmp = (((c * b) / d) - a) / d;
elseif (c <= 1.55e+130)
tmp = t_0;
else
tmp = t_1;
end
tmp_2 = tmp;
end
(-.f64 (/.f64 b c) (*.f64 (/.f64 d c) (/.f64 a c))): 0 points increase in error, 0 points decrease in error
(-.f64 (/.f64 b c) (Rewrite<= times-frac_binary64 (/.f64 (*.f64 d a) (*.f64 c c)))): 0 points increase in error, 1 points decrease in error
(-.f64 (/.f64 b c) (/.f64 (Rewrite<= *-commutative_binary64 (*.f64 a d)) (*.f64 c c))): 0 points increase in error, 7 points decrease in error
(-.f64 (/.f64 b c) (/.f64 (*.f64 a d) (Rewrite<= unpow2_binary64 (pow.f64 c 2)))): 7 points increase in error, 0 points decrease in error
(Rewrite<= unsub-neg_binary64 (+.f64 (/.f64 b c) (neg.f64 (/.f64 (*.f64 a d) (pow.f64 c 2))))): 0 points increase in error, 1 points decrease in error
(+.f64 (/.f64 b c) (Rewrite<= mul-1-neg_binary64 (*.f64 -1 (/.f64 (*.f64 a d) (pow.f64 c 2))))): 1 points increase in error, 0 points decrease in error
(Rewrite<= +-commutative_binary64 (+.f64 (*.f64 -1 (/.f64 (*.f64 a d) (pow.f64 c 2))) (/.f64 b c))): 0 points increase in error, 7 points decrease in error
if -5.5e88 < c < -6.20000000000000004e-71 or 2.1999999999999999e-60 < c < 1.55e130
Initial program 16.2
\[\frac{b \cdot c - a \cdot d}{c \cdot c + d \cdot d}
\]
Applied egg-rr11.9
\[\leadsto \color{blue}{\frac{1}{\mathsf{hypot}\left(c, d\right)} \cdot \frac{b \cdot c - a \cdot d}{\mathsf{hypot}\left(c, d\right)}}
\]
if -6.20000000000000004e-71 < c < 2.1999999999999999e-60
Initial program 21.4
\[\frac{b \cdot c - a \cdot d}{c \cdot c + d \cdot d}
\]
Simplified21.4
\[\leadsto \color{blue}{\frac{b \cdot c - a \cdot d}{\mathsf{fma}\left(c, c, d \cdot d\right)}}
\]
Proof
(/.f64 (-.f64 (*.f64 b c) (*.f64 a d)) (fma.f64 c c (*.f64 d d))): 0 points increase in error, 0 points decrease in error
(/.f64 (-.f64 (*.f64 b c) (*.f64 a d)) (Rewrite<= fma-def_binary64 (+.f64 (*.f64 c c) (*.f64 d d)))): 2 points increase in error, 0 points decrease in error
(-.f64 (*.f64 (/.f64 b d) (/.f64 c d)) (/.f64 a d)): 0 points increase in error, 0 points decrease in error
(-.f64 (Rewrite<= times-frac_binary64 (/.f64 (*.f64 b c) (*.f64 d d))) (/.f64 a d)): 0 points increase in error, 0 points decrease in error
(-.f64 (/.f64 (Rewrite=> *-commutative_binary64 (*.f64 c b)) (*.f64 d d)) (/.f64 a d)): 7 points increase in error, 0 points decrease in error
(-.f64 (/.f64 (*.f64 c b) (Rewrite<= unpow2_binary64 (pow.f64 d 2))) (/.f64 a d)): 0 points increase in error, 7 points decrease in error
(Rewrite<= unsub-neg_binary64 (+.f64 (/.f64 (*.f64 c b) (pow.f64 d 2)) (neg.f64 (/.f64 a d)))): 0 points increase in error, 0 points decrease in error
(+.f64 (/.f64 (*.f64 c b) (pow.f64 d 2)) (Rewrite<= mul-1-neg_binary64 (*.f64 -1 (/.f64 a d)))): 0 points increase in error, 0 points decrease in error
(Rewrite<= +-commutative_binary64 (+.f64 (*.f64 -1 (/.f64 a d)) (/.f64 (*.f64 c b) (pow.f64 d 2)))): 7 points increase in error, 0 points decrease in error
herbie shell --seed 2022343
(FPCore (a b c d)
:name "Complex division, imag part"
:precision binary64
:herbie-target
(if (< (fabs d) (fabs c)) (/ (- b (* a (/ d c))) (+ c (* d (/ d c)))) (/ (+ (- a) (* b (/ c d))) (+ d (* c (/ c d)))))
(/ (- (* b c) (* a d)) (+ (* c c) (* d d))))