0 / 0 / 0
Регистрация: 16.06.2015
Сообщений: 1

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

16.06.2015, 12:30. Показов 24507. Ответов 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
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
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
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
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
1742 / 638 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:07
Цитата Сообщение от testuser2 Посмотреть сообщение
Добавлю еще битовые сдвиги
какой из этих битовых сдвигов нужно использовать чтобы написать ту функцию узнавания "размера окна" LZX
0
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
23.11.2024, 08:10
Левый конечно же )
1
Испарился
 Аватар для HackerVlad
1742 / 638 / 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
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
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
1742 / 638 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
23.11.2024, 08:34
Цитата Сообщение от testuser2 Посмотреть сообщение
Надо Deg2 не инициализировал
А как его инициализировать? И почему ты не указал об этом в своём коде?
0
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
23.11.2024, 08:37
HackerVlad, так там же процедура инициализации есть. Ты бы тему прочитал от начала, понял бы что к чему.
0
Испарился
 Аватар для HackerVlad
1742 / 638 / 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
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
23.11.2024, 08:47
Цитата Сообщение от HackerVlad Посмотреть сообщение
А как сделать так чтобы LeftBitShift всё-таки заработал тут
Хорош прикалываться, нужно выполнить initDeg2 просто перед вычислениями
1
Испарился
 Аватар для HackerVlad
1742 / 638 / 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
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
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
779 / 296 / 17
Регистрация: 21.01.2023
Сообщений: 512
23.11.2024, 10:04
Цитата Сообщение от testuser2 Посмотреть сообщение
там же процедура инициализации есть
А зачем старый вариант на умножениях заменён на новый на степенях? Я понимаю, что он выполняется один раз на старте, поэтому не влияет на производительность, но смысла менять не вижу.
0
1393 / 850 / 92
Регистрация: 08.02.2017
Сообщений: 3,628
Записей в блоге: 2
23.11.2024, 10:09
Цитата Сообщение от Mikle Quits Посмотреть сообщение
производительность, но смысла менять не вижу.
Просто чтоб понятнее суть была )
0
Испарился
 Аватар для HackerVlad
1742 / 638 / 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru