3

为什么数学运算 Math.sqrt(x*x+y*y) 比 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));
    }
}
4

1 回答 1

3

hypot通常以特殊方式实现以避免溢出和下溢问题。请注意,当or太大sqrt(x*x+y*y)时返回无穷大,当两者都太小时返回零。xyxy

我认为解决这个困难的通常方法是计算z = x/y,检查是否z*z在合理范围内,然后找到sqrt(1 + z*z) * y. 太大z*z了可以直接退货xz*z太小可以退货y

__ieee754_hypot查看in顶部的评论eglibc-2.11.3,我看到以下评论:

   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.

除非溢出或下溢,否则我看不出为什么eglibc会发生所有这些的原因。x*x+y*y

于 2013-03-11T21:59:14.367 回答