Helpex - Trao đổi & giúp đỡ Đăng nhập
2

Tôi đang viết mã một chương trình trong vb.net bằng Visual Studio 2015. Tôi đang cố gắng tìm ra cách sửa đổi các bit riêng lẻ trong một số nguyên 16 bit. Thứ tự byte kiểu dữ liệu số là một ít-Ấn Độ và như sau:

  • nguồn gốc (2 bit)
  • được gắn thẻ (1 bit)
  • có thể định địa chỉ (1 bit)
  • giao thức (12 bit)
Field:  [ origin ] [tagged] [addressable] [protocol]
Bits:    16 15      14       13            12 11 10 9 8 7 6 5 4 3 2 1

Trong đoạn mã ví dụ dưới đây, tôi đang cố gắng tìm ra cách đặt nguồn gốc, được gắn thẻ, có thể định địa chỉ và giao thức trong biến "i" là một số nguyên 16 bit.

  Dim i As UInt16 = 0
  Dim origin As Byte = 0          ' Message origin indicator
  Dim tagged As Byte = 0          ' Determines usage of the Frame Address target field (0 or 1)
  Dim addressable As Byte = 0     ' Message includes a target address (0 or 1)
  Dim protocol As UInt16 = 1024   ' Protocol number: must be 1024 (decimal)

Có ai có thể cung cấp một ví dụ vb.net về cách tôi có thể cập nhật biến "i" để nó chứa các giá trị bit cho nguồn gốc, được gắn thẻ, có thể định địa chỉ và giao thức không?

2 hữu ích 0 bình luận 3.1k xem chia sẻ
0

Bạn có thể sử dụng kết hợp orđể đặt các bit riêng lẻ >><<để dịch chuyển các bit.

Ví dụ: để đặt hai byte từ được gắn thẻ, có thể định địa chỉ và giao thức, bạn có thể thực hiện:

Dim tagged As Byte = 1          ' Determines usage of the Frame Address target field (0 or 1)
Dim addressable As Byte = 1     ' Message includes a target address (0 or 1)
Dim protocol As UInt16 = 1026   ' Protocol number: must be 1024 (decimal)

sendbuf(0) = sendbuf(0) or tagged ' bit 0
sendbuf(0) = sendbuf(0) or (addressable << 1) ' bit 1
sendbuf(0) = sendbuf(0) or ((protocol << 2) and 255) ' first 6 bits of protocol

sendbuf(1) = sendbuf(1) or (protocol >> 6) ' next 6 bits of protocol

Bạn có thể cần phải điều chỉnh nó - tôi đã không theo liên kết, vì vậy tôi không hoàn toàn chắc chắn những bit nào sẽ đi đâu (có 14 bit để vừa với 2 byte).

0 hữu ích 0 bình luận chia sẻ
0

Ánh xạ các giá trị bit bằng cách sử dụng các giá trị nhị phân trong một kiểu liệt kê. 1 = 1, 2 = 10, 4 = 100, v.v. Sau đó, bạn có thể chỉ định biến của mình bằng cách sử dụng kiểu liệt kê. Bạn cũng có thể kết hợp các giá trị thành một kiểu liệt kê mới (xem ProtocolX).

Để cung cấp các giá trị ban đầu, chỉ cần thêm kiểu liệt kê mà bạn muốn sử dụng.

    ' switch bits on 1, 5, 13, 14, 16
    i = FrameSectionEnum.ProtocolBit1 + FrameSectionEnum.ProtocolBit5 +
        FrameSectionEnum.AddressableBit13 +
        FrameSectionEnum.TaggedBit14 + FrameSectionEnum.OriginBit16
    PrintBits(i)

Để bật một số bit và bảo toàn các bit khác, hãy sử dụng OR.

    ' switch bits on 2 and 3 using a combined value. preserve other bits
    i = SetOn(i, FrameSectionEnum.ProtocolX)
    PrintBits(i)

Để tắt một số bit và bảo toàn các bit khác, hãy sử dụng AND và NOT.

    ' switch bits off 1 and 5
    i = SetOff(i, FrameSectionEnum.ProtocolBit1 + FrameSectionEnum.ProtocolBit5)
    PrintBits(i)

Danh sách các chức năng tiện ích:

Kiểm tra xem các bit nhất định có được bật không:

Function CheckBit(i As Integer, bit As FrameSectionEnum) As Integer
    Return If((i And bit) = bit, 1, 0)
End Function

Đặt các bit trên, bảo toàn các bit khác:

Function SetOn(i As Integer, bit As FrameSectionEnum) As Integer
    Return i Or bit
End Function

Đặt các bit tắt, bảo toàn các bit khác:

Function SetOff(i As Integer, bit As FrameSectionEnum) As Integer
    Return i And (Not bit)
End Function

Mã đầy đủ:

Module Module1

    Enum FrameSectionEnum
        ProtocolBit1 = 1
        ProtocolBit2 = 2
        ProtocolBit3 = 4
        ProtocolBit4 = 8
        ProtocolBit5 = 16
        ProtocolBit6 = 32
        ProtocolBit7 = 64
        ProtocolBit8 = 128
        ProtocolBit9 = 256
        ProtocolBit10 = 512
        ProtocolBit11 = 1024
        ProtocolBit12 = 2048

        AddressableBit13 = 4096

        TaggedBit14 = 8192

        OriginBit15 = 16384
        OriginBit16 = 32768

        ProtocolX = ProtocolBit2 + ProtocolBit3
    End Enum


    Sub Main()

        Dim i As UInt16 = 0
        ' switch bits on 1, 5, 13, 14, 16
        i = FrameSectionEnum.ProtocolBit1 + FrameSectionEnum.ProtocolBit5 +
            FrameSectionEnum.AddressableBit13 +
            FrameSectionEnum.TaggedBit14 + FrameSectionEnum.OriginBit16
        PrintBits(i)

        ' switch bits on 2 and 3 using a combined value. preserve other bits
        i = SetOn(i, FrameSectionEnum.ProtocolX)
        PrintBits(i)

        ' switch bits off 1 and 5
        i = SetOff(i, FrameSectionEnum.ProtocolBit1 + FrameSectionEnum.ProtocolBit5)
        PrintBits(i)

        Console.ReadKey(True)

    End Sub

    Function SetOn(i As Integer, bit As FrameSectionEnum) As Integer
        Return i Or bit
    End Function

    Function SetOff(i As Integer, bit As FrameSectionEnum) As Integer
        Return i And (Not bit)
    End Function

    Function CheckBit(i As Integer, bit As FrameSectionEnum) As Integer
        Return If((i And bit) = bit, 1, 0)
    End Function

    Sub PrintBits(i As Integer)

        Console.Write(CheckBit(i, FrameSectionEnum.OriginBit16))
        Console.Write(CheckBit(i, FrameSectionEnum.OriginBit15))

        Console.Write(CheckBit(i, FrameSectionEnum.TaggedBit14))

        Console.Write(CheckBit(i, FrameSectionEnum.AddressableBit13))

        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit12))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit11))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit10))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit9))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit8))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit7))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit6))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit5))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit4))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit3))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit2))
        Console.Write(CheckBit(i, FrameSectionEnum.ProtocolBit1))

        Console.WriteLine()

    End Sub

End Module
0 hữu ích 0 bình luận chia sẻ
0

Định dạng tiêu đề trong câu hỏi chứa chìa khóa để đưa tất cả các bit vào đúng vị trí. Đối với cá nhân tôi, sẽ dễ hình dung hơn nếu bạn đánh số lại các bit bằng cách sử dụng chỉ mục dựa trên 0:

Field:  [ origin ] [tagged] [addressable] [protocol]
Bits:    15 14      13       12            11 10 9 8 7 6 5 4 3 2 1 0

Bắt đầu với origintrường, nó cần được dịch chuyển 14 bit sang trái, có thể được thực hiện như sau:

origin << 14

Các trường taggedaddressabletrường cần được dịch chuyển sang trái lần lượt là 13 và 12 bit, điều này có thể được thực hiện theo cách tương tự. Các protocollĩnh vực đã ở đúng nơi, vì vậy nó không cần phải được thay đổi. Tất cả chúng có thể được kết hợp với nhau với Ortoán tử như sau:

i = (origin << 14) Or (tagged << 13) Or (addressable << 12) Or protocol

Một chi tiết cuối cùng cần được giải quyết là trong VB.NET, các hoạt động dịch chuyển bit phụ thuộc vào kiểu dữ liệu đang được dịch chuyển. Trong mã của bạn ở trên, origin, tagged, và addressablecác biến là tất cả các loại Byte. Các dịch chuyển trên kiểu này sẽ được thực hiện theo modulo 8 (số lượng bit trong một byte), nghĩa là sự dịch chuyển 9 bit cũng giống như sự dịch chuyển 1 bit.

Bởi vì tất cả các thay đổi của chúng tôi đều hơn 8 bit, chúng tôi cần phải chuyển đổi sang một kiểu dữ liệu rộng hơn, nếu không mọi thứ sẽ không đi đúng chỗ. Cách dễ dàng để làm điều này là chỉ cần thay đổi khai báo của tất cả các biến thành UInt16:

Dim i As UInt16
Dim origin As UInt16 = 0
Dim tagged As UInt16 = 0
Dim addressable As UInt16 = 0
Dim protocol As UInt16 = 1024

i = (origin << 14) Or (tagged << 13) Or (addressable << 12) Or protocol

Giải pháp thay thế cho điều này là giữ nguyên các biến của bạn được khai báo và sử dụng CTypeđể chuyển đổi các trường ngay trước khi thực hiện thay đổi:

Dim i As UInt16 = 0
Dim origin As Byte = 0
Dim tagged As Byte = 0
Dim addressable As Byte = 0
Dim protocol As UInt16 = 1024

i = (CType(origin, UInt16) << 14) Or (CType(tagged, UInt16) << 13) Or (CType(addressable, UInt16) << 12) Or protocol

Cá nhân tôi thích cách đầu tiên hơn do sự ngắn gọn, nhưng sự lựa chọn là của bạn!

0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ vb.net bit-manipulation bytearray bitwise-operators bit-shift , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading