Tôi đang cố gắng ước tính độ phức tạp của thuật toán mà tôi đã viết cho trình dịch ngược Reko , trong đó tôi đang cố gắng "hoàn tác" thông tin được trình biên dịch thực hiện thành một phép chia số nguyên theo hằng số . Trình biên dịch đã chuyển bộ phận thành một nhân số nguyên và một sự thay đổi: ( x * ⌊ 2 β / n ⌋ ) > > β , nơi β là số bit của từ máy của máy tính. Phép nhân hằng số kết quả nhanh hơn rất nhiều so với phép chia trong hầu hết các kiến trúc đương đại, nhưng không còn giống với mã gốc.
Để minh họa: câu lệnh C
y = x / 10;
sẽ được trình biên dịch Microsoft Visual C ++ biên dịch theo ngôn ngữ lắp ráp
mov edx,1999999Ah ; load 1/10 * 2^32
imul eax ; edx:eax = dividend / 10 * 2 ^32
mov eax,edx ; eax = dividend / 10
Kết quả cuối cùng là thanh ghi eax
bây giờ sẽ có giá trị mong đợi y
từ mã nguồn.
Một trình dịch ngược ngây thơ sẽ dịch ngược phần trên thành
eax = ((long)eax * 0x1999999A) >> 32;
nhưng Reko nhằm mục đích làm cho đầu ra kết quả dễ đọc hơn bằng cách khôi phục hằng số được sử dụng trong phân chia ban đầu.
Thuật toán gợi ý ở trên dựa trên mô tả về bài viết này trong Wikipedia . Đầu tiên, thuật toán xử lý hệ số nhân không đổi theo tỷ lệ nghịch đảo . Nó chuyển đổi đó đến một điểm nổi số 2 β r f và sau đó quy mô nó xuống bằng 2 β để r f , nơi 0,0 < r f < 1,0 . Bước cuối cùng, tốn kém là đặt giá trị dấu phẩy động r f giữa hai số hữu tỷ a / b , c / d(bắt đầu bằng 0/1 và 1/1) và liên tục tính toán mediant cho đến khi đạt được một số tiêu chí hội tụ. Kết quả sẽ là "tốt nhất" hợp lý xấp xỉ r nghịch đảo r f .
Bây giờ, nếu bracketing đã được thực hiện với một tìm kiếm nhị phân thông thường bắt đầu từ giữa rationals và 2 β / 2 β , và tính toán điểm giữa ( một / b + c / d ) / 2 , tôi hy vọng các thuật toán để hội tụ trong các bước O ( β ) . Nhưng sự phức tạp của thuật toán là gì nếu phương tiện được sử dụng thay thế?