2013-08-06 20 views
7

tôi cần phải giải nén chút nào đó dao động từ với một giá trị lâu, ví dụ:Java có được dãy bit từ một lâu

long input = 15367 (11110000000111) 

Những gì tôi cần để sau đó làm là để trích xuất hai giá trị dài từ bản gốc dài,

First long is 5 bits starting from bit 0, so bits 0:4 = 7 (0111) 
Second long is 56 bits starting from bit 8, so bits 7:55 = 60 (1111000) 

tôi biết điều này có thể được thực hiện với chút thay đổi và tạo mặt nạ, tuy nhiên tôi không hoàn toàn chắc chắn làm thế nào để thực hiện điều đó vì vậy nó năng động mỗi lần, vì mỗi khi tôi cần phải làm điều này, dài sẽ khác nhau và các dải bit cụ thể cũng vậy.

Tôi đã đọc về BitSets và BitArrays, tuy nhiên tôi không hoàn toàn chắc chắn đây là những điều phù hợp cho công việc.

Bất kỳ lời khuyên nào về cách tốt nhất để thực hiện điều này sẽ được đánh giá cao.

Cảm ơn!

Trả lời

8

Để trích xuất nrBits bit bắt đầu từ bù đắp offset, bạn có thể làm:

public static long extractSub(final long l, final int nrBits, final int offset) 
{ 
    final long rightShifted = l >>> offset; 
    final long mask = (1L << nrBits) - 1L; 
    return rightShifted & mask; 
} 

Lưu ý người dùng của các nhà điều hành dịch phải >>>; điều này là vì vậy bạn không mang theo chút dấu hiệu xung quanh.

Đến (1L << nrBits) - 1L, nghĩa là 2^nrBits - 1. Số L là có hằng số long.

Cũng lưu ý rằng không có "kiểm tra giới hạn" (ví dụ: bù đắp hoặc số bit lớn hơn 63 hoặc âm).

+0

Chỉ cần vé, nhờ FGE! – Tony

+1

Sẽ không '' 'làm việc tốt vì' & 'cuối cùng sẽ loại bỏ dấu mở rộng' 1 '? (góc trường hợp có lợi cho bạn: bạn trích xuất các bit bên ngoài giới hạn ngoài cùng bên trái của đầu vào, ví dụ: nrBits = 32, offset> 32) – zapl

+0

Không, nó sẽ không. Nói (với 8 bit để đơn giản hóa) bạn có '10001111' và muốn trích xuất ba bit bắt đầu tại offset 3: nếu bạn sử dụng' >>> ', shift phải cho' 00010001', nhưng với '>>' nó sẽ cung cấp cho '11110001' (bit dấu được thực hiện). – fge

2

Để giải nén bit giữa chút x và y chút, trong đó x là lớn hơn của hai số, bạn có thể nói

long mask = (Math.pow(2,x+1)-1)- (Math.pow(2,y+1)-1); 
long extract = input & mask; 
+0

Thay vì 'pow (2, n)' bạn có thể sử dụng '1 << n'. Và bạn có thể có nghĩa là '&' thay vì '&&'. – arshajii

+0

Xin lỗi, một mình và bạn đã đúng - đã sửa. Thay đổi vị trí 1 n cũng tốt, có thể nhanh hơn. – user1111284

+0

Cảm ơn user1111284! – Tony

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