为什么数学运算math.sqrt(x*x+y*y(比math.hepo(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
通常以特殊方式实现,以避免溢出和下溢问题。请注意,当x
或y
太大时,sqrt(x*x+y*y)
返回无穷大,而当x
和y
都太小时,返回零。
我认为解决这个困难的通常方法是计算z = x/y
,检查z*z
是否在合理范围内,然后找到sqrt(1 + z*z) * y
。如果z*z
太大,可以简单地返回x
,如果z*z
太小,可以返回y
。
查看eglibc-2.11.3
中__ieee754_hypot
顶部的注释,我看到以下注释块:
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.
除非x*x+y*y
溢出或下溢,否则我看不出eglibc
为什么会这么做。