Страница: 1 |
Страница: 1 |
Вопрос: Работа с битами на VB6
Добавлено: 15.12.05 14:44
Автор вопроса: Glyckmen
Появилась такая проблема, пишу прогу для телефона, а там используется другой порядок битов.
Например:
b1 b2 b3 b4 b5 b6 b7 b8 - так идут биты в телефоне
b8 b7 b6 b5 b4 b3 b2 b1 - а так в компе.
Проблему переворачивания битов я решил но уж очень медленным способом.
Приблезительно так:
b1 = Right(Str((i And 1) / 1), 1) 'Вычисляем первый бит
b2 = Right(Str((i And 2) / 2), 1) 'Вычисляем второй бит
b3 = Right(Str((i And 4) / 4), 1) 'И так далее
b4 = Right(Str((i And 8) / 8), 1)
b5 = Right(Str((i And 16) / 16), 1)
b6 = Right(Str((i And 32) / 32), 1)
b7 = Right(Str((i And 64) / 64), 1)
b8 = Right(Str((i And 128) / 128), 1)
bits = b8 + b7 + b6 + b5 + b4 + b3 + b2 + b1 ' Получаем битовое представление одного байта
bins(i) = bits ' Заносим в массив
Next i
Данный код я запускаю при запуске программы, а далее где мне надо получить перевернутый байт я запускаю вот это:
b1 = Right(Str((gs And 1) / 1), 1) 'Вычисляем биты
b2 = Right(Str((gs And 2) / 2), 1)
b3 = Right(Str((gs And 4) / 4), 1)
b4 = Right(Str((gs And 8) / 8), 1)
b5 = Right(Str((gs And 16) / 16), 1)
b6 = Right(Str((gs And 32) / 32), 1)
b7 = Right(Str((gs And 64) / 64), 1)
b8 = Right(Str((gs And 128) / 128), 1)
bits = b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 'Складываем их в обратном порядке
For gs1 = 0 To 255
If bits = bins(gs1) Then Exit For 'По массиву находим эквивалент
Next gs1
sch = gs1 'Получаем число у которого биты находятся в зеркальном отображении от начального значения
Наверно мой принцип ясен и понятен всем, но при этом возникают большие тормаза при такой обработке большого кол-ва данных.
Кто сможет подсказать более простой способ переворачивания, можно даже без битов сразу байт=зеркальный байт.
Ответы
Всего ответов: 11
Номер ответа: 1
Автор ответа:
mc-black
ICQ: 308-534-060
Вопросов: 20
Ответов: 1860
Web-сайт:
Профиль | | #1
Добавлено: 15.12.05 14:58
Сделай это одной командой StrReverse
http://www.vbnet.ru/vbguide/showfunction.asp?id=36
P.S. Могут пригодиться и массивы.
Номер ответа: 2
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #2
Добавлено: 15.12.05 15:07
StrRev требует преобразования в строку, что скорости никак не добавляет: сначала число в строку, затем строковая StrRev, затем снова строку в число.
Попробуй это, должно быть намного быстрее:
Dim result As Byte, temp As Byte, i As Long
For i = 0 To 7
temp = (oldByte \ (2 ^ i)) And 1
result = result Or temp * (2 ^ (7 - i))
Next i
swap_bits = result
End Function
Debug.Print swap_bits(170)
Номер ответа: 3
Автор ответа:
Glyckmen
Вопросов: 7
Ответов: 22
Профиль | | #3
Добавлено: 15.12.05 15:22
Немного не поняли, мне надо работать именно с числами, а не со строками, в строки я перевожу что-бы получить нужную последовательность 0 и 1, далее я просто сравниваю строчку по эталонному массиву где хранятся по порядку все числа в двоичном формате от 0 до 255,и в цикле на каком индексе выполнилось условие значит это и есть новое число(где биты в зеркальном виде от исходного) но такой метод очень и очень медленный, а мне нужен алгоритм этого преобразования без перевода в строки. число=число
Вот еще пример что я хочу:
Я имею число в компьютере 185 в двоичной системе это будет выглядеть так 10111001, а в телефоне эта-же последовательность бит будет числом 157 (если на компьютере биты записать так 10011101 то тогда будем иметь число 157 т.е. зеркальное отображение бит)и для того что-бы компютер правильно понимал данные с телефона надо делать такое преобразование.
Номер ответа: 4
Автор ответа:
Glyckmen
Вопросов: 7
Ответов: 22
Профиль | | #4
Добавлено: 15.12.05 15:30
HOOLIGAN
Проверил твой код все работает, СПАСИБО, думаю это будет гораздо быстрее, сейчас вставлю это в свой проект и проверю на больших объемах, на сколько это стало быстрей.
Номер ответа: 5
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #5
Добавлено: 15.12.05 16:18
Можно это сделать вообще мгновенно
При загрузке формы один раз инициализировать массив инверсных значений, в котором каждому индексу от 0 до 255 соответствует число, являющееся инверсным к его индексу.
А когда надо будет получить развернутое число, например, 22, то просто надо взять элемент массива с индексом 22, в котором сидит готовое число 104. Быстрее ничего не придумаешь.
'глобальный массив перевернутых значений
'каждое число в массиве - инвертированный индекс
Dim Swap(0 To 255) As Byte
Function swap_bits(ByVal oldByte As Byte) As Byte
Dim result As Byte, temp As Byte, i As Long
For i = 0 To 7
temp = (oldByte \ (2 ^ i)) And 1
result = result Or temp * (2 ^ (7 - i))
Next i
swap_bits = result
End Function
Private Sub Form_Load()
'один раз инициализируем массив при загрузке формы
Dim i As Long
For i = 0 To 255
Swap(i) = swap_bits(i)
Next i
End Sub
Private Sub cmdSwap_Click()
'а теперь просто берем готовое число из массива
Debug.Print Swap(22)
End Sub
Номер ответа: 6
Автор ответа:
Страшный Сон
Вопросов: 46
Ответов: 848
Профиль | | #6
Добавлено: 15.12.05 18:25
Можно еще довести до ума:
Dim result As Byte
result = result Or (oldByte And 1) * 128
result = result Or ((oldByte \ 2) And 1) * 64
result = result Or ((oldByte \ 4) And 1) * 32
result = result Or ((oldByte \ 8) And 1) * 16
result = result Or ((oldByte \ 16) And 1) * 8
result = result Or ((oldByte \ 32) And 1) * 4
result = result Or ((oldByte \ 64) And 1) * 2
result = result Or ((oldByte \ 128) And 1)
swap_bits = result
End Function
Номер ответа: 7
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #7
Добавлено: 15.12.05 19:24
Страшный Сон, а если понадобится не Byte, а Long развернуть, будешь рисовать колбасу из 32 одинаковых строк?
Номер ответа: 8
Автор ответа:
Glyckmen
Вопросов: 7
Ответов: 22
Профиль | | #8
Добавлено: 16.12.05 00:15
Спасибо с этим все в порядке, я понял как это сделать но это действительно получается только к целому байту, у меня есть еще задача. Эта задача уже связана с обработкой рисунков из телефона, там цвет рисунка описывается двумя байтами т.е. число типа INTEGER только всегда положительное, так чтобы перевести все это в привычный для VB6 вид надо получить три числа (т.е. RGB), порядок получения цветов происходит так:
Имеем 16 битное число
b16 b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1
Цвета RGB получаются из сочетаний битов в таком порядке:
red= b13 b12 b11 b10 b9
green= b3 b2 b1 b16 b15 b14
blue= b8 b7 b6 b5 b4
для недостающих бит спереди добавляются 0 "нуль"
Эту проблему я решал точно таким-же способом как я описал в своем первом посте. По Вашему способу значит мне придется делать массив на 65536 эллементов и потом просто подставлять нужные значения, что может занять продолжительное время при инициализации формы и приличный объем памяти (у меня кстати была такая мысль в начале написания своей программы), может Вы подскажите алгоритм зеркальной замены в 16 битном числе первых 5 бит(т.е. только это кол-во бит отображены зеркально), далее 6 бит и в конце 5 бит.
Номер ответа: 9
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #9
Добавлено: 16.12.05 01:49
Выдирай нужные биты (например, and'ом) и только их обращай по массиву размером 32 и 64 элементов.
Номер ответа: 10
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #10
Добавлено: 16.12.05 05:20
делать массив на 65536 эллементов и потом просто подставлять нужные значения, что может занять продолжительное время при инициализации формы
Сколько это займет времени при инициализации формы - можно проверить, зачем полагаться на "может" или "не может" На моем компе это занимает порядка 0,4 - 0,5 сек. Много? Тогда просто вызывай функцию для каждого преобразования, подкорректировав размеры переменных (Long вместо Byte), и заменив 7 на 15.
А размер это будет занимать 65536 лонгов - ок. 260 кБ. Для сравнения пустая форма без кода при запуске отжирает порядка 2 Мб.
Хотя я не понял, при чём тут Integer? Цвета ведь занимают 5 бит, и они вполне влезают в обычный Byte. Разбил цвет на три составляющие, и затем каждую из них развернул как байт, поделил на 8, а потом слепил обратно. (2^3=8), где 3 - кол-во недостающих до 8 разрядов
Номер ответа: 11
Автор ответа:
Glyckmen
Вопросов: 7
Ответов: 22
Профиль | | #11
Добавлено: 16.12.05 10:50
Я имел ввиду в числе типа INTEGER (16 бит)содержится информация о цвете и уже из этого числа надо выделять составляющие цветов и вот эти составляющие как раз и могут иметь тип BYTE.
Я прошу прощения за плохое объяснение проблемы, чесно говоря это моя первая программа на VB6, ранше в эпоху DOS и WIN 3.1 лет 14 назад я неплохо писал программы на QB7 (QuickBASIC 7.1)? GWBAS и TurboBAS, вот решил так сказать тряхнуть стариной и снова начать программировать, при этом попутно впоминая и разбираясь в новинках.
За помощь всем СПАСИБО!