Saya mencoba memperkirakan kompleksitas suatu algoritma yang saya tulis untuk dekompiler Reko , di mana saya mencoba untuk "membatalkan" tranformasi yang dilakukan oleh kompiler ke divisi integer oleh konstanta. Kompiler telah mengubah divisi menjadi perkalian integer dan pergeseran:dimana adalah jumlah bit kata mesin komputer. Perkalian konstan yang dihasilkan jauh lebih cepat daripada pembagian di sebagian besar arsitektur kontemporer, tetapi tidak lagi menyerupai kode asli.
Untuk menggambarkan: pernyataan C.
y = x / 10;
akan dikompilasi oleh kompiler Microsoft Visual C ++ ke bahasa assembly berikut
mov edx,1999999Ah ; load 1/10 * 2^32
imul eax ; edx:eax = dividend / 10 * 2 ^32
mov eax,edx ; eax = dividend / 10
Hasil akhirnya adalah register eax
sekarang akan memiliki nilai yang diharapkan dari y
kode sumber.
Decompiler naif akan mendekompilasi di atas ke
eax = ((long)eax * 0x1999999A) >> 32;
tetapi Reko bertujuan untuk membuat output yang dihasilkan lebih terbaca dari itu dengan memulihkan konstanta yang digunakan di divisi asli.
Algoritma yang diisyaratkan di atas didasarkan pada deskripsi pada artikel ini di Wikipedia . Pertama, algoritma memperlakukan pengali konstan sebagai timbal balik yang diskalakan. Itu mengubahnya menjadi angka floating point dan kemudian skala turun untuk dimana . Langkah terakhir yang mahal adalah mengurung nilai floating point antara dua bilangan rasional , (dimulai dengan 0/1 dan 1/1) dan berulang kali menghitung perantara sampai beberapa kriteria konvergensi tercapai. Hasilnya harus menjadi pendekatan rasional "terbaik" untuk timbal balik .
Sekarang, jika bracketing sedang dilakukan dengan pencarian biner yang khas dimulai antara rasional dan , dan menghitung titik tengah , Saya berharap algoritma akan menyatu Langkah. Tapi apa kompleksitas algoritma jika mediant digunakan sebagai gantinya?