2008-08-29 29 views
33

Tôi biết rằng sau đây là đúngCó cách nào để thực hiện thay đổi bit tròn trong C# không?

int i = 17; //binary 10001 
int j = i << 1; //decimal 34, binary 100010 

Nhưng, nếu bạn chuyển quá xa, các bit rơi ra cuối cùng. Trường hợp này xảy ra là một vấn đề kích thước của số nguyên bạn đang làm việc với.

Có cách nào để thực hiện thay đổi sao cho các bit xoay quanh phía bên kia không? Tôi đang tìm một hoạt động đơn lẻ, không phải là vòng lặp for.

+0

Hoạt động của loại này sẽ được sử dụng ở đâu? Mục đích của việc xoay vòng bit là gì? Tôi không cần biết, nhưng tôi chỉ quan tâm đến việc mở rộng kiến ​​thức. Keith –

+0

một câu hỏi rất hay. Tôi vừa kiểm tra mã được tạo ra và trình biên dịch C# không tạo mã sử dụng lệnh xoay của CPU (không phải kiến ​​trúc x86 có chúng từ 8086 ...). Đây là một sự xấu hổ. C thực hiện tối ưu hóa này. Các phép quay cũng rất quan trọng đối với các tác vụ mật mã và dsp. –

Trả lời

45

Nếu bạn biết kích thước của loại, bạn có thể làm một cái gì đó như:

uint i = 17; 
uint j = i << 1 | i >> 31; 

... mà sẽ thực hiện một sự thay đổi tròn của một giá trị 32 bit.

Như một sự tổng quát để thay đổi hình tròn trái n bit, trên một biến b bit:

/*some unsigned numeric type*/ input = 17; 
var result = input << n | input >> (b - n); 


@The bình luận, dường như C# không đối xử với các bit cao các giá trị ký kết khác nhau. Tôi đã tìm thấy một số thông tin về điều này here. Tôi cũng đã thay đổi ví dụ để sử dụng một uint.

+1

Vì tôi không biết C#, các toán tử dịch chuyển có làm thay đổi số học hay logic không? Nếu số học, thì thuật toán này không thể được sử dụng cho các số nguyên đã ký 64 bit. – tzot

+0

Vì vậy, có lẽ cả hai loại 'int' và 'var' phải được thêm tiền tố với một sửa đổi 'unsigned', tất nhiên nếu C# cho phép điều đó. – tzot

+0

Cảm ơn bạn đã đánh bắt điều đó. –

9

Một năm trước, tôi đã thực hiện MD4 cho luận án đại học của tôi. Ở đây nó được thực hiện của tôi thay đổi bit tròn bằng cách sử dụng một UInt32.

private UInt32 RotateLeft(UInt32 x, Byte n) 
{ 
     return UInt32((x << n) | (x >> (32 - n))); 
} 
3

Cũng như tài liệu tham khảo về cách để làm điều đó, hai chức năng này hoạt động hoàn hảo về luân các bit 1/2word:

static public uint ShiftRight(uint z_value, int z_shift) 
{ 
    return ((z_value >> z_shift) | (z_value << (16 - z_shift))) & 0x0000FFFF; 
} 

static public uint ShiftLeft(uint z_value, int z_shift) 
{ 
    return ((z_value << z_shift) | (z_value >> (16 - z_shift))) & 0x0000FFFF; 
} 

Nó sẽ dễ dàng để mở rộng nó cho bất kỳ kích thước nhất định.

0

Ứng dụng nổi tiếng nhất là giải pháp cho vấn đề Josephus (như đã thảo luận trong Toán học Bê tông, xem http://oeis.org/A006257). Điều này về cơ bản là một câu đố không có ứng dụng rõ ràng. Trong this video, tôi đã chứng minh mối liên hệ giữa vấn đề thứ tự Josephus thứ hai và cây cân bằng hoàn chỉnh. Nó vẫn không phải là một ứng dụng, nhưng di chuyển nhẹ theo đúng hướng.

Các vấn đề liên quan