2 つの乱数を乗算するよりも、数値を 2 乗する方が速いのはなぜですか?
-
21-09-2019 - |
質問
2 つの 2 進数の乗算には n^2 の時間がかかりますが、数値の 2 乗は何らかの方法でより効率的に実行できます。(n はビット数です) どうしてそうなるのでしょうか?
それとも不可能なのでしょうか?これは狂気だ!
解決
2 つの数値を乗算するには O(N^2) よりも効率的なアルゴリズムが存在します (Karatsuba、Pollard、Schönhage-Strassen などを参照)。
「任意の 2 つの N ビット数値を乗算する」と「任意の N ビット数値を 2 乗する」という 2 つの問題は同じ複雑さです。
我々は持っています
4*x*y = (x+y)^2 - (x-y)^2
したがって、N ビット整数の 2 乗に O(f(N)) 時間がかかる場合、2 つの任意の N ビット整数の積も O(f(N)) で取得できます。(つまり、2x N ビット合計、2x N ビット平方、1x 2N ビット合計、および 1x 2N ビット シフト)
そして明らかに私たちは持っています
x^2 = x * x
したがって、2 つの N ビット整数の乗算に O(f(N)) かかる場合、N ビット整数の 2 乗は O(f(N)) で実行できます。
積 (または二乗) を計算するアルゴリズムは、同じ漸近コストで二乗 (または積) を計算するアルゴリズムを提供します。
他の回答で述べたように、二乗の場合、高速乗算に使用されるアルゴリズムを簡素化できます。ゲインは f(N) 自体ではなく、f(N) の前の定数に影響します。
他のヒント
Nの桁数を二乗が速く2つのランダムのn桁の数字を乗算するよりもできます。グーグルで私はこの記事を発見しました。これは、任意精度演算についてですが、それはあなたが求めて何に関連する可能性があります。これで、著者はこれを言うます:
大きな整数を二乗で、すなわちX ^ 2 =(XN-1、XN-2、...、X1、X0)フォームXIの^ 2多くのクロス積項* XJとXJ * xiが同等です。彼ら 一度だけして、計算する必要が 左が二重にするためにシフト。 N桁の二乗演算であります のみ(N ^ 2 + N)/ 2を使用して実行 単精度乗算
他の人のようには速く、任意の数の間の定期的な乗算よりも1.5倍または2倍程度とすることができ乗、指摘しています。計算の利点はどこから来るのでしょうか?それは対称です。レッツは1011
の二乗を計算し、我々が活用できるというパターンを発見してみてください。 u0:u3
最下位に最上位から数のビットを表します。
1011 // u3 * u0 : u3 * u1 : u3 * u2 : u3 * u3
1011 // u2 * u0 : u2 * u1 : u2 * u2 : u2 * u3
0000 // u1 * u0 : u1 * u1 : u1 * u2 : u1 * u3
1011 // u0 * u0 : u0 * u1 : u0 * u2 : u0 * u3
あなたは要素が対角線を形成し、それらを無視するui * ui
ためi=0, 1, ..., 4
考慮した場合、、あなたはui * uj
ための要素のi ≠ j
を2回繰り返していることがわかります。
そのため、あなたがする必要があるすべては左シフトして、対角以下の要素のための積和を計算し、それを倍増です。あなたは最終的には、対角要素を追加したいです。 2Xスピードアップがどこから来た今、あなたは見ることができます。実際には、スピードアップがあるため、対角と、余分な操作の1.5倍程度である。
あなたは2のべき乗で数を掛ける意味しますか?これは通常、迅速結果は、単純なビットシフトすることによって計算することができるので、任意の2個の乱数を乗算よりも長いです。しかし、心に留めて、現代のマイクロプロセッサは、これらのタイプの計算にブルートフォースシリコンの多くを捧げ、ほとんどの算術は、古いマイクロプロセッサ
に比べて速度がまばゆいばかりに行われていること私はそれを持っています!
2 * 2
よりも高価です
2 << 1
(注意点は、それが唯一の場合の動作である。)
あなたは乗算(a+b)×(c+d)
を拡大するとします。これは、4回の個々の乗算にまで分割:。a×c + a×d + b×c + b×d
(a+b)²
を展開したい場合は、しかし、それはわずか3回の乗算(と倍増)必要があります。a² + 2ab + b²
を
うまくいけば、これは普通の乗算平方を実行するときに可能であり、高速化のいくつかの洞察力を与えることを開始します。
すべての偉大な質問の初!私はこのような多くの質問があった希望ます。
それは私が思いついた方法は、唯一の算術複雑で一般的な乗算にO(N Nログ)であることが判明したので。あなたは、任意の数のXを表すことができます。
X = x_{n-1} 2^{n-1} + ... + x_1 2^1 + x_0 2^0
Y = y_{m-1} 2^{m-1} + ... + y_1 2^1 + y_0 2^0
ここで、
x_i, y_i \in {0,1}
そして
XY = sum _ {k=0} ^ m+n r_k 2^k
ここで、
r_k = sum _ {i=0} ^ k x_i y_{k-i}
(N + M)ログ(N + M)の時間における各kについてr_kの値を見つけるためにFFTのちょうどまっすぐアプリケーションである
次に、各r_kのためにあなたは、オーバーフローがどのように大きな判断しなければならないし、それに応じてそれを追加します。数この手段はO(N Nログ)算術操作
を二乗するためのはr_k値を追加することができ、より効率的にビット操作が結合(NログN Nログログ)Oを得ることがSchönhage-Strassenのアルゴリズムを使用して。
あなたの質問に正確な答えはすでにエリックBainvilleによって投稿されています。
しかし、あなたはがは整数を乗算するためのより良い境界が存在するというだけの理由で数を二乗するためにはるかに優れたO(N ^ 2)よりも拘束得ることができます!
は、二乗操作がとても速くなり得る、メモリから一つだけの負荷を必要とします。
任意の長さの整数の場合、乗算は、典型的には、O(N²)であるが、大きな整数のためにこれを低減アルゴリズムがあります。
あなたが乗算のA のことでのB のへの単純なO(N²)アプローチを前提とした場合は、、そして A の各ビットのためにあなたがシフトする必要があります B のそのビットが1である場合に、アキュムレータに追加します。 のA のあなたは3Nシフトと加算を必要とします。
の各ビットのためになお、
( x - y )² = x² - 2 xy + y²
そこで
x² = ( x - y )² + 2 xy - y²
各場合 Y の2つのないXよりも大きい最大のパワーであり、これは、より低い正方形、2つのシフト二加算に還元を与えます。 のN の各反復で減少しているとして、あなたは(対称手段、それは三角形ではなく長方形に各ポイントを訪問)効率ゲインを得ることができますが、それはまだO(N²)。
ですは別の、より良い対称性を悪用するためにあるかもしれません。
A ^ 2 (+ bの)*(+ b)は+ B ^ 2など。 66 ^ 2 =(66 + 6)(66-6)+ 6 ^ 2 = 72 * 60 + 36 = 4356
^ n個だけ電源ルールを使用するために、
66 ^ 4 = 4356 ^ 2
私はNビット乗算することによって、問題を解決したいと思います 数の
AビットであるA(N-1)、A(N-2)........ A(1)、A(0)。
BビットがB(N-1)B(N-2)........ B(1)B(0)である。
ユニーク乗算ビットはなり生成数Aの正方形のためのA(0)のための - > A(0)···A(n-1)の (1) - > A(1)···A(N-1)など 従って、合計操作がされる
OP = N + N-1 + N-2 ....... + 1 従ってOP = N ^ 2 + N / 2。 漸近表記はO(N ^ 2)となるように
とAとBとの乗算のためにN ^ 2回のユニークな乗算が生成されます 漸近表記はO(N ^ 2)となるように
2の平方根 N が2 N / 2 又は2 N >> 1 ので、あなたの数はの力である場合あなたが力を知っていれば2つのすべてが完全に簡単です。多重にもsimplier:2 4 * 2 8 が2 4 + 8 。あなたがやったこの文では意味がありません。
、それは(常に、熱心な読者に証明左)が、これは2 ^ 2N + 2 ^(N + 1)のように二乗することができる、(2 ^ N + B)のように表すことができます。 B + B ^ 2。私たちは、その後、Bがゼロに等しいというような点まで、拡張を繰り返すことができます。私はそれをあまりにもハード見ていないが、直感的に、それはあなたが二乗関数は、汎用の乗算よりも少ないalgorithmical措置をとる作ることができるはずかのように感じます。
私はあなたの文で完全に間違っていると思います。
乗算2つの2進数取り N ^ 2時間
乗算2つの32ビットの数字は正確に1つのクロックサイクルを取ります。 64ビットプロセッサでは、私は、乗算、2つの64ビット数が正確に1つのクロックサイクルを取ることを前提としています。それも、1つのクロックサイクルで、私のこと、32ビットプロセッサができる2つの乗算64ビットの番号は驚かないだろう。
yet squaring a number can be done more efficiently somehow.
数を二乗はちょうどので、それは単純な乗算である、自分自身で番号を乗算されます。 CPUには「四角」の操作はありません。
たぶん、あなたは、「2のべき乗を乗じ」と「二乗」混乱しています。 2を乗算する「左」への全てのビット一つの位置をシフトすることによってimplemetedすることができます。 4を乗じは「左」への全てのビットを2つの位置をずらしています。 8、3つの位置によって。しかし、このトリックは2つだけのパワーに適用されます。