The Math.hypo function



为什么数学运算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通常以特殊方式实现,以避免溢出和下溢问题。请注意,当xy太大时,sqrt(x*x+y*y)返回无穷大,而当xy都太小时,返回零。

我认为解决这个困难的通常方法是计算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为什么会这么做。

最新更新