タグ付けされた質問 「perfect-square」

30
整数の平方根が整数かどうかを判断する最も速い方法
long値が完全な二乗かどうか(つまり、その平方根が別の整数かどうか)を判断する最も速い方法を探しています。 私は組み込みMath.sqrt() 関数を使用して簡単な方法で実行しましたが、整数のみのドメインに制限することでより速く実行する方法があるかどうか疑問に思っています。 ルックアップテーブルを維持することは非現実的です(二乗が2 63未満の整数が約2 31.5 個あるため)。 ここに私が今やっている非常にシンプルで簡単な方法があります: public final static boolean isPerfectSquare(long n) { if (n < 0) return false; long tst = (long)(Math.sqrt(n) + 0.5); return tst*tst == n; } 注:この関数は、多くのプロジェクトオイラー問題で使用しています。したがって、他の誰もこのコードを保守する必要はありません。そして、この種のマイクロ最適化は実際に違いをもたらす可能性があります。課題の一部はすべてのアルゴリズムを1分未満で実行することであり、この関数はいくつかの問題では何百万回も呼び出される必要があるためです。 私は問題のさまざまな解決策を試しました: 徹底的なテスト0.5の結果、少なくとも私のマシンでは、Math.sqrt()の結果に追加する必要がないことがわかりました。 平方根逆高速は速かったが、それは、n> = 410881.に対して誤った結果を与えたが、によって提案されたようBobbyShaftoe、我々はN <410881のためFISRハックを使用することができます。 ニュートンの方法は、に比べてかなり遅いですMath.sqrt()。これはおそらく、Math.sqrt()ニュートンの方法に似たものを使用しているためですが、ハードウェアに実装されているため、Javaよりもはるかに高速です。また、ニュートンの方法では、依然としてdoubleの使用が必要でした。 整数演算のみが関与するようにいくつかのトリックを使用した修正ニュートン法は、オーバーフローを回避するためにいくつかのハックを必要とし(この関数をすべての正の64ビット符号付き整数で機能させたい)、それでもは遅くなりましたMath.sqrt()。 バイナリチョップはさらに遅くなりました。バイナリチョップは、64ビット数の平方根を見つけるために平均で16パスを必要とするため、これは理にかなっています。 ジョンのテストによると、使用してorステートメントは、より高速なC ++で使用するよりもあるswitchが、JavaやC#での間に違いはないようであるorとswitch。 (64のブール値のプライベート静的配列として)ルックアップテーブルを作成してみました。次に、switchやorstatementの代わりに、とだけ言いif(lookup[(int)(n&0x3F)]) { test } else return …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.