私が考えることができる唯一の欠点は、二乗するとオーバーフローする大きな数を扱うときです。
たとえば、Javaの場合:
int x = Integer.MAX_VALUE / 1000000; //2147
int y = Integer.MAX_VALUE / 5000; //429496
System.out.println("x < y: " + (x < y)); //true
System.out.println("x*x: " + (x * x)); //4609609
System.out.println("y*y: " + (y * y)); //-216779712 - overflows!
System.out.println("x*x < y*y: " + (x * x < y * y)); //false - incorrect result due to overflow!
また、Math.pow()をまったく同じ数で使用し、次の値から返されたdoubleからintにキャストすると、何が起こるかということも注目に値しますMath.pow()
。
System.out.println("x^2: " + (int) (Math.pow(x, 2))); //4609609
System.out.println("y^2: " + (int) (Math.pow(y, 2))); //2147483647 - double to int conversion clamps to Integer.MAX_VALUE
System.out.println("x^2 < y^2: " + ((int) (Math.pow(x, 2)) < (int) (Math.pow(y, 2)))); //true - but for the wrong reason!
それは働いていますか?いいえ、にy*y
固定されてInteger.MAX_VALUE
おり、x*x
未満であるため、正しい答えを出しましたInteger.MAX_VALUE
。x*x
固定されていた場合はInteger.MAX_VALUE
、間違った答えが得られます。
同様の原則は、フロートとダブル(オーバーフローする前に明らかに広い範囲を持っていることを除く)と、静かにオーバーフローを許可する他の言語にも適用されます。