бит из байта

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Wasup!
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 21.06.2005 (Вт) 11:09

бит из байта

Сообщение Wasup! » 29.09.2006 (Пт) 13:09

Необходимо извлечь из стрового представления шестнадцатеричного числа n бит. Начиная с некоторого байта в этом числе и некоторого бита в этом байте. Результат возвращается, как строка. Если извлекается больше бит, чем есть в байте, то последующие берутся из следующего байта.

У меня получился такой вариант:
Код: Выделить всё
Option Explicit
Sub ExtractBit()
'Извлекает из строкового Hex числа sHex, из iByte байта
'iBlength  бит, начиная с iBstart бита.
'Байты в числе считаются слева направо начиная с 1
'Биты в байте считаются справа налево начиная с 1

Dim sHex        As String   'hex число в строковом представлении
Dim iByte       As Integer  'байт из которого извлекаются биты
Dim iBstart     As Integer  'бит с которого начинается извлечение
Dim iBlength    As Integer  'число бит, м.б. >8, тогда биты извлекаются из следующего байта числа

Dim iTmpHex     As Integer
Dim iNewBstart  As Integer
Dim sTmpHex     As String
Dim sBit        As String
Dim n           As Integer
Dim i           As Integer

sHex = "9CA3C539" '10011100 10100011 11000101 00111001
iByte = 2         'со второго байта
iBstart = 5       'c пятого бита
iBlength = 8      '8 бит

On Error GoTo exception
n = RoundUp((8 - iBstart + iBlength) / 8) 'число байт, которое нужно взять из sHex
sTmpHex = Mid(sHex, iByte * 2 - 1, n * 2)
Debug.Print "sTmpHex: " & sTmpHex
iTmpHex = CInt("&H" + sTmpHex)
iNewBstart = iBstart + ((n - 1) * 8)
Debug.Print "iNewBstart: " & iNewBstart
If iNewBstart > Len(sTmpHex) * 4 Or iByte <= 0 Or iBstart <= 0 Or iBlength <= 0 Then
    Err.Raise -20001
End If
For i = iNewBstart - 1 To iNewBstart - iBlength Step -1
     
     sBit = sBit + IIf((iTmpHex And (2 ^ i)) <> 0, "1", "0")
Next
Debug.Print sBit

Exit Sub
exception:
    MsgBox "Выход за границы числа", vbCritical, "ExtractBit()"
End Sub

Public Function RoundUp(ByVal dNumber As Double) As Double
'Округляет число до целого в большую сторону: 1.1=2 1.9=2
If dNumber <> Fix(dNumber) Then
    RoundUp = Fix(dNumber) + 1
Else
    RoundUp = dNumber
End If
End Function


Скажите, пожалуйста, есть более быстрые и оптимальные способы?
Или может быть есть какие-то ошибки.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 29.09.2006 (Пт) 14:18

Конечно есть более быстрые способы. Преобразовать строку в число, и использовать побитовые операции
Весь мир матрица, а мы в нем потоки байтов!

Wasup!
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 21.06.2005 (Вт) 11:09

Сообщение Wasup! » 02.10.2006 (Пн) 8:37

А можно подробнее, я вроде так и делаю.
Код: Выделить всё
iTmpHex = CInt("&H" + sTmpHex)  '(хотя, конечно, лучше clng())
sBit = sBit + IIf((iTmpHex And (2 ^ i)) <> 0, "1", "0")

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 02.10.2006 (Пн) 8:42

Он имел ввиду, не собирать биты по одному в строку, а сразу извлечь все необходимые биты и сдвинуть вправо.
Lasciate ogni speranza, voi ch'entrate.

Wasup!
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 21.06.2005 (Вт) 11:09

Сообщение Wasup! » 02.10.2006 (Пн) 15:24

Если сделать так, то как потом преобразовать полученное число в двоичную строку? (результат должен быть строкой)
Есть какой-то аналог функции hex, для возврата двоичных чисел?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 02.10.2006 (Пн) 15:27

Нет, аналога нет.
А зачем именно строкой?
Если так, то лучше преобразуй в двоичный вид два байта, которым принадлежит нужный диапазон, а затем используй Mid$().
Lasciate ogni speranza, voi ch'entrate.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 97

    TopList