Ir para conteúdo
Fórum Script Brasil
  • 0

Melhor Forma De Manipular Bits No Vb .net


Thiago Alencar

Pergunta

Qual e a melhor forma de se manipular bits?

Estou numa situacao em que preciso organizar a ordem dos bits de um byte em um grande loop, então digo "melhor" no aspecto do performance, com menos instrucoes de conversoes possivel, mais instrucoes nativas do cpu (baixo nivel, tipo xor).

Pra ser mais especifico:

Eu tenho uma array shift Integer() que contem a ordem dos bits. E claro um array "buffer" de bytes.

Por exemplo:

Dim shift as Integer() {2,1,0,7,5,4,6,3}

dim buffer as Byte() 'variable with data

no caso acima e com um byte tipo 10010111, o mesmo deve se tornar 00110011.

assim:

------------------------

De: 10010111

Para : 00110011

------------------------

sguindo a ordem do "shift" pelos seus indices.

Parece um problema simples, mas a performance e' realmente critica aqui (o loop e' imenso).

Com o codigo que tenho atualmente consigo realizar isso mas construindo o byte com uma concatecanao de um objeto StringBuilder, porem a velocidade e' muito lenta:

Private Sub ShiftMe(ByVal buffer As Byte(), ByVal shift As Integer())

      'Lets shift byte's columns
      Dim worker As New System.Text.StringBuilder
      Dim bkupArray As Boolean()
      ReDim bkupArray(7)

      For p As Integer = 0 To buffer.GetUpperBound(0)

         'Separate each bit of byte
         bkupArray(0) = buffer(p) And 1
         bkupArray(1) = (buffer(p) And 2) >> 1
         bkupArray(2) = (buffer(p) And 4) >> 2
         bkupArray(3) = (buffer(p) And 8) >> 3
         bkupArray(4) = (buffer(p) And 16) >> 4
         bkupArray(5) = (buffer(p) And 32) >> 5
         bkupArray(6) = (buffer(p) And 64) >> 6
         bkupArray(7) = (buffer(p) And 128) >> 7

         'Create Shifted byte
         buffer(p) = 0 'clean old byte
         worker.Remove(0, worker.Length)
         worker.Append(bkupArray(shift(7)) & bkupArray(shift(6)) & bkupArray(shift(5)) & bkupArray(shift(4)) & bkupArray(shift(3)) & bkupArray(shift(2)) & bkupArray(shift(1)) & bkupArray(shift(0)))

         buffer(p) = StrToByteArray(worker.ToString)
      Next
   End Sub

meu estoque de criatividade de logicas já se esgotou, se alguém tiver alguma dica está valendo..

valeu!

Editado por Thiago Alencar
Link para o comentário
Compartilhar em outros sites

6 respostass a esta questão

Posts Recomendados

  • 0

Vixi, acho que você meio que viajou, hein. Isso, pelo menos, "parece" simples.

Eu faria um laço e giraria a variavel com os indices, assim pegaria os dados com as ordens e pegaria do dado a ser processado com uma Substring, e depois converteria para byte... Bem mais simples do que usar um String Builder...

Falows!

Link para o comentário
Compartilhar em outros sites

  • 0

Eu faria assim:

Dim shift As Integer() = {2, 1, 0, 7, 5, 4, 6, 3}
Dim buffer As Byte() = {1, 0, 0, 1, 0, 1, 1, 1}
Dim destino(8) As Byte

Dim i As Integer = 0
For Each pos As Integer In shift
    destino(i) = buffer(pos)
    i += 1
Next

Certo? ;)

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Ola!

não é tão simples como parece, se você rodar esse codigo penso que encontrara problemas com os valores.

não entendi muito bem sua declaracao do byte:

Dim buffer As Byte() = {1, 0, 0, 1, 0, 1, 1, 1}

pra mim isso seria:

buffer(0) = 00000001

buffer(1) = 00000000

buffer(2) = 00000000

buffer(3) = 00000001

buffer(4) = 00000000

buffer(5) = 00000001

buffer(6) = 00000001

buffer(7) = 00000001

e não buffer(0) = 10010111 que acho que é o que você quis dizer...correto ou estou enganado?

Estou com o mesmo tópico em um outro forum (thescripts.com) e ate agora ninguém postou um codigo com melhor performance que o que mostrei aqui. Se quiser dar uma olhada: http://www.thescripts.com/forum/showthread...900#post2587900

teve um cara que deu uma ideia bacana de usar o pow, porem a performance foi horrivel (como postei la no post do resultado, quase o dobro do tempo)

qualquer ideia está valendo..

T+!

Editado por Thiago Alencar
Link para o comentário
Compartilhar em outros sites

  • 0

Realmente eu tinha imaginado que o buffer era composto pelos bits. Entretanto, dá pra fazer isso também com um BitArray:

Dim shift As Integer() = {2, 1, 0, 7, 5, 4, 6, 3}
Dim buffer As New BitArray(New Byte() {151})

Dim i As Integer = 0
Dim temp As Boolean

For Each pos As Integer In shift
    temp = buffer(i)
    buffer(i) = buffer(pos)
    buffer(pos) = temp
    i += 1
Next

O exemplo acima é só com 1 byte (151 = 10010111).

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...