2013-04-08 27 views
12

Tôi rất mới với C# (và C nói chung cho rằng vấn đề) Tôi nhận được một giá trị byte trả về từ một nguồn bên ngoài đại diện cho các trạng thái của 8 chân đầu vào trên cổng của một thiết bị IO để tôi nhận được một giá trị 0-255 đại diện cho mẫu nhị phân có trên cổng.Làm cách nào để tách từng bit ra khỏi một byte?

Làm thế nào tôi có thể loại bỏ các bit riêng lẻ và đặt chúng như bool vars, làm như vậy một cái gì đó như thế này:

if (inputBuffer[1] == 1) 
{ 
    IO.Input0 = true; 
    IO.Input1 = false; 
    IO.Input2 = false; 
    IO.Input3 = false; 
    IO.Input4 = false; 
    IO.Input5 = false; 
    IO.Input6 = false; 
    IO.Input7 = false; 
}  

Tôi lẽ overexplaining những gì tôi đang cố gắng để đạt được nhưng nghĩ điều này sẽ cho là tốt nhất Ví dụ mặc dù rất không thực tế, làm thế nào tôi có thể đạt được điều này tốt hơn để thiết lập các biến dựa trên một giá trị byte 0-255.

+3

C# và C có thể trông bề ngoài tương tự theo tên và theo một số cú pháp của chúng, nhưng tôi sẽ không nhóm chúng lại với nhau. C# và Java có thể chia sẻ nhiều hơn C# và C. IMO tên C# chỉ là một mưu đồ tiếp thị thông minh của Microsoft. – DAB

+0

@DAB Phải, vì 'ISO/IEC 23270: 2006' không có cùng một vòng với nó. ':)' –

Trả lời

12

Sử dụng bitwise-và (&). Giả sử Input0 đại diện cho các bit quan trọng nhất:

IO.Input0 = (inputBuffer & 0x01) == 0x01; 
IO.Input1 = (inputBuffer & 0x02) == 0x02; 
IO.Input2 = (inputBuffer & 0x04) == 0x04; 
IO.Input3 = (inputBuffer & 0x08) == 0x08; 
IO.Input4 = (inputBuffer & 0x10) == 0x10; 
IO.Input5 = (inputBuffer & 0x20) == 0x20; 
IO.Input6 = (inputBuffer & 0x40) == 0x40; 
IO.Input7 = (inputBuffer & 0x80) == 0x80; 

Bạn cũng có thể thực hiện một phương pháp khuyến nông như sau:

public static bool IsBitSet(this byte b, int bit) 
{ 
    if(bit < 0 || bit > 7) 
     throw new ArgumentOutOfRangeException("bit must be between 0 and 7"); 

    byte bitToCheck = (byte)(0x01 << bit); 

    return (b & bitToCheck) == bitToCheck; 
} 

Mà bạn sau đó có thể gọi như:

IO.Input4 = inputBuffer.IsBitSet(4); 
+0

Cảm ơn đã làm việc hoàn hảo :) chính xác những gì tôi cần làm –

4

Sử dụng bitmask và & -operator để tìm ra điều này

byte b = 100; 

if(b&1 == 1) { } //bit 1 is set 
if(b&2 == 2) { } //bit 2 is set 
if(b&4 == 4) { } //bit 3 is set 
... 
+1

Không biên dịch. Bạn đã viết một số mã 'C' ... –

+0

Vì vậy, có gì sai với nó? –

+0

Trước khi chỉnh sửa, bạn đã có 'if (b & 1) {} // bit 1 được đặt', nhưng bây giờ bạn đã chỉnh sửa và nó đã chính xác. –

2

Tôi nghĩ rằng một lớp tự viết có thể hữu ích. Lớp có thể chứa 8 bit và hàm tạo mất một byte. Trong hàm tạo, bạn có thể tính toán các bit đơn.

public class myByte 
{ 
    bool Input0 = false; 
    bool Input1 = false; 
    bool Input2 = false; 
    bool Input3 = false; 
    bool Input4 = false; 
    bool Input5 = false; 
    bool Input6 = false; 
    bool Input7 = false;   

    public myByte(byte b) 
    { 
     //written by Ic. 
     Input0 = b & 0x01 == 0x01; 
     Input1 = b & 0x02 == 0x02; 
     Input2 = b & 0x04 == 0x04; 
     Input3 = b & 0x08 == 0x08; 
     Input4 = b & 0x10 == 0x10; 
     Input5 = b & 0x20 == 0x20; 
     Input6 = b & 0x40 == 0x40; 
     Input7 = b & 0x80 == 0x80; 
    } 
    ... //getter setter ... 
} 
2

Bạn có thể thực hiện việc này.

int x= inputBuffer[1]; 

bit1 = ((x>>7)&1==1); 
bit2 = ((x>>6)&1==1); 
bit3 = ((x>>5)&1==1); 
bit4 = ((x>>4)&1==1); 
bit5 = ((x>>3)&1==1); 
bit6 = ((x>>2)&1==1); 
bit7 = ((x>>1)&1==1); 
bit8 = (x&1==1); 

Để có được chút 1 từ nói 11.101.110 giá trị mà bạn cần phải thay đổi ngay đầu tiên BT 7 lần và sau đó thực hiện VÀ hoạt động với 1 sẽ cho bạn biết giá trị là 1 hoặc 0 và cùng giải pháp áp dụng cho bit khác nữa .

2

Nếu dữ liệu được cung cấp cho bạn dưới dạng Byte và mỗi bit đã được đeo mặt nạ, thì tôi sẽ để nguyên nó. Chuyển đổi chúng sang loại khác là không cần thiết, nó sẽ là một công việc phụ không có lợi ích. Để có bit chính xác, chỉ cần sử dụng mẫu mặt nạ bit

private bool GetMaskedBit(var inputBuffer , int mask) 
{ 
    return ((inputBuffer & mask) != 0); 
} 

Bằng cách này bạn phân tích bộ đệm và bit yêu cầu mà bạn muốn, điều này sẽ trả lại xem bit đã được đặt hay chưa.

+2

Tại sao không chỉ 'return (inputBuffer & mask)! = 0'? – DaveDev

+0

Yeap, khá đúng! – Jegan

+0

Họ cần phải được chuyển đổi thành các bool vars riêng lẻ cho mỗi đầu vào vì nó đơn giản hoá nội dung ở nơi khác –

2

Bạn có thể sử dụng lớp BitArray.

var bitArray = new BitArray(inputBuffer); 
IO.Input1 = bitArray[byteIndex * 8 + 1]; 

Hoặc

var bitArray = new BitArray(new byte[] { inputBuffer[1] }); 
IO.Input1 = bitArray[1]; 

Bạn cũng có thể lặp lại nó như là một tập hợp các giá trị Boolean, và thực hiện thao tác Bitwise trên toàn bộ bộ sưu tập.

Nó rõ ràng không phải là biểu diễn như các tùy chọn khác được cung cấp ở đây (chi phí phân bổ) nhưng nó cung cấp một API rất gọn gàng để tính toán bit.

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