Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Работа с битами на VB6 Добавлено: 15.12.05 14:44  

Автор вопроса:  Glyckmen
Появилась такая проблема, пишу прогу для телефона, а там используется другой порядок битов.
Например:
b1 b2 b3 b4 b5 b6 b7 b8 - так идут биты в телефоне
b8 b7 b6 b5 b4 b3 b2 b1 - а так в компе.

Проблему переворачивания битов я решил но уж очень медленным способом.
Приблезительно так:
For i = 0 To 255
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

Данный код я запускаю при запуске программы, а далее где мне надо получить перевернутый байт я запускаю вот это:
'Далее имеем переменную gs типа Integer в которой хранится число от 0 до 255 и нам в этом числе надо поменять биты в зеркальном отображении

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-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #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, затем снова строку в число.

Попробуй это, должно быть намного быстрее:

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

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
Можно еще довести до ума:

Function swap_bits(ByVal oldByte As Byte) As Byte
    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-сайт: sharpc.livejournal.com
 Профиль | | #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, вот решил так сказать тряхнуть стариной и снова начать программировать, при этом попутно впоминая и разбираясь в новинках.
За помощь всем СПАСИБО!

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам