2010-05-23 54 views
8

Nếu bạn có số nhị phân 10110, làm thế nào tôi có thể lấy nó để trả về 11111? ví dụ: một số nhị phân mới đặt tất cả các bit thành 1 sau 1 đầu tiên, có một số ví dụ tương tự được liệt kê bên dưới:Độ dài của các bit được sử dụng trong int

101 phải trả về 111 (3 bit length) 011 phải trả về 11 (2 bit length) 11100 trả lại 11111 (chiều dài 5 bit) 101010101 phải trả lại 111111111 (chiều dài 9 bit)

Làm cách nào để có được cách dễ nhất trong Java? Tôi có thể đưa ra một số phương pháp nhưng chúng không phải là "khá".

+3

Đó là tất cả ở đây: http://graphics.stanford.edu/~seander/bithacks.html –

Trả lời

6

Bạn có thể sử dụng mã này:

int setBits (int value) 
{ 
    value |= (value >> 1); 
    value |= (value >> 2); 
    value |= (value >> 4); 
    value |= (value >> 8); 
    value |= (value >> 16); 
    return value; 
} 

Ý tưởng là tận cùng bên trái 1 sẽ được sao chép vào tất cả các vị trí trên bên phải.

EDIT: Cũng hoạt động tốt với số âm value. Nếu bạn thay thế int bằng long, hãy thêm một câu hỏi thêm |=: value |= (value >> 32). Nói chung, sự thay đổi cuối cùng phải là một sức mạnh của 2 đó là ít nhất một nửa kích thước value tính theo bit.

+2

Điều đặc biệt tốt đẹp với thuật toán đó là nó sử dụng lại các hoạt động trước. Naively tôi sẽ thực hiện 32 ca. –

+1

Nếu bạn nhìn vào việc thực hiện cho 'Integer # highestOneBit()' trong JDK, bạn sẽ thấy cùng một thuật toán, mặc dù bước cuối cùng được thiết kế chỉ phân phối một bit duy nhất, yêu cầu undoing capture trong câu trả lời của hleinone. – seh

6

đã không được kiểm tra, nhưng một cái gì đó như thế này sẽ không sao:

long setBits(long number) { 
    long n = 1; 
    while (n <= number) n <<= 1; 
    return n - 1; 
} 
+0

1 cho suy nghĩ bên ngoài hộp :-) –

+1

này sẽ không làm việc nếu ' số' là số âm. Nó sẽ nhanh nếu 'số' thường nhỏ, nhưng chậm nếu' số' được phân phối đồng đều trên phạm vi của nó. – doublep

+0

Đúng về âm bản, tôi không nghĩ về điều đó. Và sẽ nhanh hơn nếu tôi bắt đầu từ đầu kia. Nhưng 63 lần lặp (tối đa) không thực sự chậm; và câu trả lời nằm ngoài đầu tôi. Rõ ràng, giải pháp của hleinone thổi nó ra khỏi nước ... :) – Amadan

0

Không hiệu quả nhất, nhưng đơn giản nhất,

int i = (1 << (int)(Math.log(n)/Math.log(2)+1)) - 1; 

Nó sẽ làm việc cho 31 bit đầu tiên của int và 63 bit đầu tiên trong thời gian dài.

10
+0

Để có đầy đủ: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html#highestOneBit(int) – Eric

+0

Hmmm .. Có vẻ như tôi không thể đăng liên kết. SO không thích dấu ngoặc đơn. – Eric

+3

Wow, không có ý tưởng Java có chức năng này ... đây chắc chắn là hầu hết các eleagant ở đây. – Amadan

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