Why the math operation Math.sqrt(x*x+y*y) is much faster than Math.hypo(x,y)?
public class Teste {
public static void main(String[] args) {
long ta = System.currentTimeMillis();
for( double x=0,y=0; x<5000000; x++,y+=2 ){
double d = Math.sqrt(x*x+y*y);
}
long tb = System.currentTimeMillis();
System.err.println((tb-ta));
ta = System.currentTimeMillis();
for( double x=0,y=0; x<5000000; x++,y+=2 ){
double d = Math.hypot(x,y);
}
tb = System.currentTimeMillis();
System.err.println((tb-ta));
}
}
hypot is usually implemented in a special way to avoid issues with overflow and underflow. Notice that sqrt(x*x+y*y) returns infinity when x or y is too large and zero when both x and y are too small.
I think the usual way to get around this difficulty is by computing z = x/y, checking if z*z is in a reasonable range, and then finding sqrt(1 + z*z) * y. If z*z is too big, you can simply return x, and if z*z is too small, you can return y.
Looking at the comment at the top of __ieee754_hypot in eglibc-2.11.3, I see the following chunk of a comment:
So, compute sqrt(x*x+y*y) with some care as
follows to get the error below 1 ulp:
Assume x>y>0;
(if possible, set rounding to round-to-nearest)
1. if x > 2y use
x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
where x1 = x with lower 32 bits cleared, x2 = x-x1; else
2. if x <= 2y use
t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
y1= y with lower 32 bits chopped, y2 = y-y1.
I can't see a reason for why eglibc does all this unless x*x+y*y overflows or underflows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With