Câu hỏi Tối ưu hóa hoạt động bitwise trong C


Tôi đã có một vấn đề trong tay như thế này: "Bài tập 2-6. Viết một hàm setbits (x, p, n, y) trả về x với n bit bắt đầu tại vị trí p được đặt thành n bit phải của y, để lại các bit khác không thay đổi. "

Tôi đã viết một chức năng cho điều này như dưới đây. Điều này đang hoạt động như mong đợi.

int func_setx(int x,int p,int n,int y)
{
    int a_t= ~0 << (p+n);
    int b_t= ~a_t >> n;
    int x_t= x& (a_t | b_t);    // a temporary x which has the bits to be changed as 0 , rest of the bits unchanged.

    int mask= (y << p) & (~(~0 << (p+n)));     // a mask which has required bits from y in positions to be set , rest all bits 0.

    printf("\nCheckpoint : mask= %x  x_t= %x\n",mask,x_t);

    int result= mask|x_t;
    return result;
}

Nhưng tôi bằng cách nào đó cảm thấy logic dài và có thể được tối ưu hóa, nhưng không thể nghĩ ra bất kỳ cách nào khác. Bất cứ ai có thể đề nghị bất kỳ tối ưu hóa này xin vui lòng?


8
2018-06-27 04:26


gốc


Có thể bạn sẽ tìm thấy câu trả lời tại Bit Twiddling Hacks - và bạn nên đánh dấu trang ngay cả khi bạn không tìm thấy câu trả lời ở đó. - Jonathan Leffler
Nhiều bản sao, ví dụ: k & r tập thể dục nhầm lẫn với bit-hoạt động và trả về x với n bit bắt đầu từ vị trí p được đặt tới bit n phải của y, để lại các bit khác không thay đổi và Đặt bit trong C - Paul R


Các câu trả lời:


Để thực hiện một n mặt nạ bit:

mask_y = (1U << n) - 1;

Để bắt đầu nó tại bit p:

mask_x = mask_y << p;

Xóa các bit thích hợp trong x:

x &= ~mask_x;

Trích xuất các bit từ y:

y &= mask_y;

Upshift chúng đến vị trí p:

y <<= p;

Đặt nó tất cả cùng nhau:

result = x | y;

Hoặc ở dạng gọn nhẹ hơn:

mask = (1U << n) - 1;
result = x & ~(mask << p);
result |= (y & mask) << p; 

10
2018-06-27 04:37



Giả sử số nguyên 32 bit, nếu n == 32, giải pháp này gây ra hành vi không xác định. Trường hợp đó chỉ là return y, tuy nhiên, thật dễ dàng để trở thành trường hợp đặc biệt. Cách khác, sử dụng 1ULL (hoặc tuy nhiên bạn muốn có loại 64 bit) thay vì 1U. - Carl Norum
1 không chỉ cho mã mà còn giải thích những gì nó làm từng bước - legends2k
Carl, bình luận của bạn đúng là một phần của câu trả lời của bạn. - Jim Balter
Đó là nhiều hơn một phần của câu trả lời, thực sự, đó là lý do tại sao tôi để lại một bình luận. NBD. - Carl Norum