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)場合は無限大を返し、とが小さすぎる場合は 0を返します。xyxy

z = x/yこの問題を回避する通常の方法は、 を計算し、 が妥当な範囲内にあるかどうかを確認z*zしてから、 を見つけることだと思いますsqrt(1 + z*z) * yz*zが大きすぎる場合は を返すだけでよく、小さすぎるx場合z*zは を返すことができますy

の上部にあるコメント__ieee754_hypoteglibc-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 に答える