Rekoデコンパイラー用に作成したアルゴリズムの複雑さを推定しようとしています。ここで、コンパイラーが定数による整数除算に行った変換を「取り消す」ようにしています。コンパイラーは除算を整数の乗算とシフトに変換しました:、ここではコンピューターのマシンワードのビット数です。結果の定数乗算は、ほとんどの現代的なアーキテクチャでの除算よりもはるかに高速ですが、元のコードに似ていません。(X * ⌊ 2 β / N ⌋ )> > β β
説明するには:Cステートメント
y = x / 10;
Microsoft Visual C ++コンパイラによって、次のアセンブリ言語にコンパイルされます
mov edx,1999999Ah ; load 1/10 * 2^32
imul eax ; edx:eax = dividend / 10 * 2 ^32
mov eax,edx ; eax = dividend / 10
最終的な結果は、レジスタeax
がy
ソースコードからの期待値を持つようになることです。
素朴な逆コンパイラは上記を逆コンパイルします
eax = ((long)eax * 0x1999999A) >> 32;
しかし、Rekoは、元の除算で使用されていた定数を復元することにより、結果の出力を読みやすくすることを目指しています。
上記で示唆されたアルゴリズムは、Wikipediaのこの記事の説明に基づいています。まず、アルゴリズムは定数乗数をスケーリングされた逆数として扱います。これは、浮動小数点数への変換を、次いでによってそれをダウンスケーリングに、。最後の高価なステップは、2つの有理数、(0/1と1/1で始まる)の間の浮動小数点値、値を繰り返し計算することです。2 β R F 0.0 < RのF < 1.0 R F / B 、C / D (+のC )/(B + D )のR のR F いくつかの収束基準に達するまで。結果は、逆数に対する「最良の」有理近似になります。
ここで、ブラケット0/2と間で始まり、中点を計算する一般的なバイナリ検索でブラケットが行われていた場合、アルゴリズムがステップで収束することを期待しています。しかし、代わりにメディアントが使用されている場合、アルゴリズムの複雑さはどうなりますか?