Xoay phải các bit trong C

Jan 03 2021

Tôi đang làm bài tập 2-8 trong K&R yêu cầu chúng ta viết hàm rightrot(int x, int n)sao cho tất cả các bit xđược dịch chuyển n lần sang phải với các bit rơi ra khỏi đầu bên phải xuất hiện lại ở đầu bên trái.

Đây là giải pháp đã cố gắng của tôi, trong đó tôi thay đổi từng bit một:

int rightrot(int x, int n)
{
    int i, rmb;

    for(i = 0; i < n; ++i)
    {
        // get right-most bit
        rmb = x & 1;

        // shift 1 to right
        x = x >> 1;

        // if right-most bit is set, set left-most bit
        if (rmb == 1)
            x = x | (~0 ^ (~0 >> 1) );
    }

    return x;
}

Khi tôi thực hiện rightrot(122, 2), tôi mong muốn nhận được 94từ 1221111010941011110. Thay vào đó, tôi nhận được 30điều đó xảy ra 0011110. Rõ ràng, phương pháp đặt bit ngoài cùng bên trái của tôi không hoạt động như tôi mong đợi. Có ai phát hiện ra một lỗi rõ ràng không? Tôi chỉ đang tìm hiểu về cách chụp các bit và những thứ tương tự.

LƯU Ý: Tôi có kỹ thuật thiết lập bit ngoài cùng bên trái từ bài đăng này.

Trả lời

7 mch Jan 02 2021 at 23:21

Hãy phân tích (~0 ^ (~0 >> 1) ):

~0-1
~0 >> 1một lần nữa -1, nếu bit dấu là 1rightshift sẽ điền vào các bit mới với 1s.
-1 ^ -10.
x = x | 0x.

Giải pháp là bạn nên sử dụng các kiểu dữ liệu không dấu nếu bạn muốn thực hiện các hoạt động bit.

Vì vậy, bạn nên sử dụng dòng x = x | (~0u ^ (~0u >> 1) );
Để tránh các vấn đề khác, tham số xcũng nên được unsigned int.

https://ideone.com/7zPTQk