С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.61/121: Рейтинг темы: голосов - 121, средняя оценка - 4.61
0 / 0 / 0
Регистрация: 16.06.2015
Сообщений: 1

Чтение и изменение бита в числе

16.06.2015, 12:30. Показов 23991. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Столкнулся с такой проблемой - через СOM порт от контроллера получаю массив байт данных, сохраняю их в виде переменной Double.
Visual Basic
1
2
3
4
5
6
Case Is = 2         
        intInf(0) = Asc(MSComm1.Input) '
        intInf(1) = Asc(MSComm1.Input) ' 
        intInf(2) = Asc(MSComm1.Input) ' 
        intInf(3) = Asc(MSComm1.Input) ' 
       ' и т.д

Каждый установленный бит в числе имеет смысловую нагрузку. Вопрос -каким образом можно обращаться к отдельным битам в числе (Аналог команды в ассемблере setb Acc.N (установить бит N в "1") и clr Acc.N (установить бит N в "0")). Пока что додумался только до преобразования полученного числа в бинарный вид при помощи функции

Visual Basic
1
2
3
4
5
6
7
8
9
10
Public Function ToBin(ByVal bByte As Byte) As String
Dim i As Integer
For i = 0 To 7
If bByte And 2 ^ i Then
ToBin = 1 & ToBin
 Else
ToBin = 0 & ToBin
 End If
Next i
End Function
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.06.2015, 12:30
Ответы с готовыми решениями:

Операция "сброса бита в числе" (число и номер бита)
Как в калькуляторе сделать сброс бита в числе (число и номер бита)? В сети, нашел только это: #### value=(sbyte) value &...

Инвертировать 2 средних бита в числе
люди помогите пожалуйста с заданием. Часть кода имеется, составил число, вот только с инвертацией битов застрял. long...

Установка бита в двоичном числе
Добрый день! Столкнулся с проблемой при установке бита в двоичном числе. использую функцию bts, однако при запуске выдает следующую ошибку:...

35
34 / 31 / 1
Регистрация: 06.01.2017
Сообщений: 300
06.12.2017, 04:27
Студворк — интернет-сервис помощи студентам
Возможно, кому-то понадобятся функции побитового преобразования числа в строку и наоборот:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Function MaskL(ByVal MaskS As String) As Long
 Dim p As Long, m As Long, L As Long
 L = Len(MaskS)
 m = 0
 For p = 0 To L - 1
  If Mid(MaskS, p + 1, 1) = "1" Then m = BitPut(m, p)
 Next p
 MaskL = m
End Function
Function MaskS(ByVal MaskL As Long) As String
 Dim p As Long, S As String
 S = ""
 For p = 0 To 15
  If BitGet(MaskL, p) Then
   S = S & "1"
  Else
   S = S & "0"
  End If
 Next p
 MaskS = S
End Function
Проверочная программка:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sub MaskCheck()
 Dim m1 As Long, m2 As Long, m3 As Long
 Dim s1 As String, s2 As String, s3 As String
 Dim rA As String, rB As String
 
 Call InitDeg2
 s1 = "011000":
 s2 = "000011"
 s3 = "011111"
 m1 = MaskL(s1)
 m2 = MaskL(s2)
 m3 = MaskL(s3)
 
 rA = Mid(MaskS(m1 Xor m3), 1, 5)
 rB = Mid(MaskS(m2 ND m3), 1, 5)
End Sub
1
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
21.07.2024, 14:54
32бит версия )
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Private Deg2(1 To 32) As Long
Function MaskS(ByVal lNum As Long) As String
    Static init As Boolean
    Dim i As Long, bAr(63) As Byte
    If init Then Else InitDeg2: init = True
'    MaskS2 = String(32, vbNullChar)
    For i = 1 To 32
'        Mid$(MaskS2, i, 1) = CBool(lNum And Deg2(i)) And 1
        bAr((i - 1) * 2) = (CBool(lNum And Deg2(i)) And 1) + 48
    Next
    MaskS = bAr
End Function
Function MaskL(sInp As String) As Long
    Static init As Boolean
    Dim i As Long, bAr() As Byte
    If init Then Else InitDeg2: init = True
    bAr = sInp
    For i = 1 To Len(sInp)
'        If Mid$(sInp, i, 1) = "1" Then
        If bAr((i - 1) * 2) = 49 Then MaskL = MaskL Or Deg2(i)
    Next
End Function
Sub InitDeg2()
    Dim p As Long
    
    Deg2(1) = 1
    For p = 2 To 31
        Deg2(p) = 2 * Deg2(p - 1)
    Next
    Deg2(32) = -2 * Deg2(31)
End Sub
Code
1
2
?MaskL(MaskS(-548722587))
-548722587
2
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 08:00
Добавлю еще битовые сдвиги
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Private Deg2(31) As Long
 
Private Sub initDeg2()
    Dim i&
    For i = 0 To 30
        Deg2(i) = 2 ^ i
    Next
    Deg2(i) = -2 ^ i
End Sub
 
Function LeftBitShift(ByVal lVal As Long, ByVal bitCnt As Long) As Long
    LeftBitShift = lVal * Deg2(bitCnt) '2 ^ bitCnt
End Function
Function RightBitShift(ByVal lVal As Long, ByVal bitCnt As Long) As Long
    RightBitShift = lVal \ Deg2(bitCnt) '2 ^ bitCnt
End Function
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:07
Цитата Сообщение от testuser2 Посмотреть сообщение
Добавлю еще битовые сдвиги
какой из этих битовых сдвигов нужно использовать чтобы написать ту функцию узнавания "размера окна" LZX
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 08:10
Левый конечно же )
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:26
testuser2, о, спасибо, осталось теперь только написать эту функцию

Добавлено через 10 минут
testuser2, что-то у меня не работает, можешь найти где у меня ошибка?

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Option Explicit
 
Private Const tcompSHIFT_LZX_WINDOW As Long = 8
Private Const tcompTYPE_LZX As Long = 3
Private Deg2(31) As Long
 
Private Sub initDeg2()
    Dim i&
    For i = 0 To 30
        Deg2(i) = 2 ^ i
    Next
    Deg2(i) = -2 ^ i
End Sub
 
Private Function LeftBitShift(ByVal lVal As Long, ByVal bitCnt As Long) As Long
    LeftBitShift = lVal * Deg2(bitCnt) ' 2 ^ bitCnt
End Function
 
Private Function TCOMPfromLZXWindow(ByVal w As Long) As Long
    TCOMPfromLZXWindow = LeftBitShift(w, tcompSHIFT_LZX_WINDOW) Or tcompTYPE_LZX
End Function
 
Private Sub Command1_Click()
    MsgBox TCOMPfromLZXWindow(21), vbInformation, "0x" & Hex(TCOMPfromLZXWindow(21)) ' 3 это неправильно...
End Sub
Что я не так написал?
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 08:33
Цитата Сообщение от HackerVlad Посмотреть сообщение
Что я не так написал?
Надо Deg2 инициализировать

Добавлено через 1 минуту
Можно проще сделать
Visual Basic
1
2
3
4
Public Function TCOMPfromLZXWindow(ByVal w As Long) As Long
'    Return w << tcompSHIFT_LZX_WINDOW Or tcompTYPE_LZX
    TCOMPfromLZXWindow = w * 2 ^ tcompSHIFT_LZX_WINDOW Or tcompTYPE_LZX
End Function
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:34
Цитата Сообщение от testuser2 Посмотреть сообщение
Надо Deg2 не инициализировал
А как его инициализировать? И почему ты не указал об этом в своём коде?
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 08:37
HackerVlad, так там же процедура инициализации есть. Ты бы тему прочитал от начала, понял бы что к чему.
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:40
Цитата Сообщение от testuser2 Посмотреть сообщение
Ты бы тему прочитал от начала, понял бы что к чему
Ну да, поленился всё читать просто.

Вот короче:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Option Explicit
 
Private Const tcompSHIFT_LZX_WINDOW As Long = 8
Private Const tcompTYPE_LZX As Long = 3
Private Deg2(31) As Long
 
Private Sub initDeg2()
    Dim i&
    For i = 0 To 30
        Deg2(i) = 2 ^ i
    Next
    Deg2(i) = -2 ^ i
End Sub
 
Private Function LeftBitShift(ByVal lVal As Long, ByVal bitCnt As Long) As Long
    LeftBitShift = lVal * Deg2(bitCnt) ' 2 ^ bitCnt
End Function
 
'Private Function TCOMPfromLZXWindow(ByVal w As Long) As Long
'    TCOMPfromLZXWindow = LeftBitShift(w, tcompSHIFT_LZX_WINDOW) Or tcompTYPE_LZX
'End Function
 
Public Function TCOMPfromLZXWindow(ByVal w As Long) As Long
'    Return w << tcompSHIFT_LZX_WINDOW Or tcompTYPE_LZX
    TCOMPfromLZXWindow = w * 2 ^ tcompSHIFT_LZX_WINDOW Or tcompTYPE_LZX
End Function
 
Private Sub Command1_Click()
    MsgBox TCOMPfromLZXWindow(21), vbInformation, "0x" & Hex(TCOMPfromLZXWindow(21)) ' 5379 тут уже правильно...
End Sub
 
Private Sub Form_Load()
    Dim i As Long
    
    For i = 0 To 31
        Deg2(i) = 0
    Next
End Sub
Так правильно 5379

Добавлено через 28 секунд
А как сделать так чтобы LeftBitShift всё-таки заработал тут
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 08:47
Цитата Сообщение от HackerVlad Посмотреть сообщение
А как сделать так чтобы LeftBitShift всё-таки заработал тут
Хорош прикалываться, нужно выполнить initDeg2 просто перед вычислениями
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:53
testuser2, а что ж ты мне сразу не сказал!? я всё не понимал, почему меня не работает

Добавлено через 2 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
Хорош прикалываться
Я реально не понимал. Неужели сложно было сказать что процедуру нужно запускать в Form_Load.
Ура! Теперь всё работает.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Option Explicit
Private Const tcompSHIFT_LZX_WINDOW As Long = 8
Private Const tcompTYPE_LZX As Long = 3
Private Deg2(31) As Long
 
Private Sub initDeg2()
    Dim i&
    For i = 0 To 30
        Deg2(i) = 2 ^ i
    Next
    Deg2(i) = -2 ^ i
End Sub
 
Private Function LeftBitShift(ByVal lVal As Long, ByVal bitCnt As Long) As Long
    LeftBitShift = lVal * Deg2(bitCnt) ' 2 ^ bitCnt
End Function
 
Private Function TCOMPfromLZXWindow(ByVal w As Long) As Long
    TCOMPfromLZXWindow = LeftBitShift(w, tcompSHIFT_LZX_WINDOW) Or tcompTYPE_LZX
End Function
 
Private Sub Command1_Click()
    MsgBox TCOMPfromLZXWindow(21), vbInformation, "0x" & Hex(TCOMPfromLZXWindow(21)) ' 5379 тут уже правильно...
End Sub
 
Private Sub Command2_Click()
    MsgBox TCOMPfromLZXWindow(15), vbInformation, "0x" & Hex(TCOMPfromLZXWindow(15)) ' 3843 теперь всё правильно
End Sub
 
Private Sub Form_Load()
    initDeg2
End Sub
1
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 09:30
Cамый оптимум вариант для VB6/VBA
Visual Basic
1
2
3
4
5
Function TCOMPfromLZXWindow(ByVal w As Long) As Long
'    Return w << tcompSHIFT_LZX_WINDOW Or tcompTYPE_LZX
'    2 ^ tcompSHIFT_LZX_WINDOW = &H100
    TCOMPfromLZXWindow = w * &H100 Or tcompTYPE_LZX
End Function
1
 Аватар для Mikle Quits
759 / 278 / 14
Регистрация: 21.01.2023
Сообщений: 399
23.11.2024, 10:04
Цитата Сообщение от testuser2 Посмотреть сообщение
там же процедура инициализации есть
А зачем старый вариант на умножениях заменён на новый на степенях? Я понимаю, что он выполняется один раз на старте, поэтому не влияет на производительность, но смысла менять не вижу.
0
1384 / 838 / 91
Регистрация: 08.02.2017
Сообщений: 3,512
Записей в блоге: 1
23.11.2024, 10:09
Цитата Сообщение от Mikle Quits Посмотреть сообщение
производительность, но смысла менять не вижу.
Просто чтоб понятнее суть была )
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 10:23
Ну разницы в скорости всё равно думаю никакой не будет, какой бы вы способ ни выбрали...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.11.2024, 10:23
Помогаю со студенческими работами здесь

Инвертирование определенного бита в заданном числе
Напишите программу, которая инвертирует определенный бит в заданном числе (биты при этом нумеруются с 0, начиная с младших).

Побитовыми операциями поменять местами в числе по 2 бита
Задали побитовыми операциями поменять местами в числе по 2 бита то есть в веденном числе последние два бита в начало за ними...

Ошибка при определении нужного бита в большем числе
Здравствуйте, столкнулся с такой проблемой. Я не могу определить какой бит у меня находится в определенной позиции в числе...

Найти номер первого (последнего) справа нулевого бита в целом числе a
Найти номер первого (последнего) справа нулевого бита в целом числе a.

Чтение бита четности
Здравствуйте. У меня есть вопрос: Как считать бит четности через с++? Написана программа которая будет общаться с устройством через...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru