Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/47: Рейтинг темы: голосов - 47, средняя оценка - 4.64
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3

Определение изменения бит в байте

27.08.2021, 19:18. Показов 11402. Ответов 128

Студворк — интернет-сервис помощи студентам
Всем ку!
Возник вопрос по оптимальному методу определения изменившихся бит в байте.
Два байта прилетают по сети и имеют следующий вид:

Суть в следующем (на примере байта Е8):
0-й, 3-й и 6-й биты "работы", говорят о включенном или выключенном состоянии участка. 1-й, 2-й, 4-й, 5-й, ... биты - определения сторон (L/R) соотв. участков. Они всегда находятся в одном из двух состояний: 01 либо 10. Состояний 00 или 11 не бывает.
Так вот, в идеале, требуется определить момент смены состояний, допустим с 01 на 10, при установленном бите "работы".
Если бит "работы" не установлен, то изменения состояний бит сторон пофигу.
Пока я делаю это так (без учета бита "работы"):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
            if ( _byte != _oldByte )
            {
                int _change = _byte ^ _oldByte;
 
                for ( int i = 7; i > -1; i-- )
                {
                    if ( ( _change >> i & 1 ) == 1 ) 
                    { 
                        lstSndIndex.Add( i ); //здесь запись в лист индекса изменившихся бит для последующей отправки в сеть
                    }
                }
 
                _oldByte = _byte;   
            }
т.е. я сравниваю текущее состояние с некоторым прошлым значением.
Можно ли как-то сделать иначе?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.08.2021, 19:18
Ответы с готовыми решениями:

Поменять порядок бит в байте
Есть некий байт, необходимо порядок его первых 3х бит поменять на обратный! Подскажите Добавлено через 6 минут По сути надо 0 и 2...

Обмен двух бит в байте местами
Например, требуется обменять местами 2-й и 3-й бит в байте, если один из них == 1. Можно сделать это так: int _byte = 9; //...

В байте не восемь бит.
Мне знакомый показал статейку следующего вида: Внимание! Путаница в терминологии. Читать всем! zaff » 14 авг 2009, 18:09 ...

128
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.09.2021, 10:50
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от escoult Посмотреть сообщение
и Элд Хасп, не знает
???
Откуда такие выводы?

Как были сформулированы условия вначале топика, так и работает код.
Тесты я вам показывал для того чтобы вы в этом сами убедились.

Вчера вечером, разобрались с тем, что по факту условия задачи иные.
И естественно предложенный ранее код не будет для них работать.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
01.09.2021, 11:05  [ТС]
Вот 10 различных ситуаций:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        //    1  2  3  4  5
        //0: 0L-0R-0R-0L-0R
        //1: 1L-0R-0R-1L-0R
        //2: 1L-0R-0R-1R-0R
        //3: 0L-1R-0R-0R-1R
        //4: 0L-1R-1R-0L-1L
        //5: 0R-1R-1R-0R-1L
        //6: 0L-0R-1L-1R-1L
        //7: 0L-0R-0L-1L-1R
        //8: 0L-0R-0L-1L-0R
        //9: 0L-1L-0L-0L-0R
        static readonly int[] situation = new int[] { 17698, 18211, 19235, 22826, 13674, 
                                                      22892, 15074, 22178, 18082, 17562 };
escoult, тестируем ваш последний вариант:
C#
1
2
3
4
5
6
7
8
9
10
            while ( true )
            {
                Console.Write("Номер ситуации: ");
                int idx = Convert.ToInt16( Console.ReadLine() );
                int currval = situation[ idx ];
                DisplayBytes( currval, 15, 3 );
                BridgePorts( currval );
 
                Console.WriteLine();
            }
Ситуация №0:
Code
1
2
3
4
Номер ситуации: 0
100 010 100 100 010
 
Номер ситуации:
Все нормально, ничего не отправляется.

Ситуация №1:
Code
1
2
3
4
5
Номер ситуации: 1
100 011 100 100 011
00 00 00 00 10
 
Номер ситуации:
Опа, вы отправили R-сторону 1-го участка, а включена L (левая). А L-сторону 4-го участка вообще "забыли"...
Весь код теста
C#
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class Program
    {
        //    1  2  3  4  5
        //0: 0L-0R-0R-0L-0R
        //1: 1L-0R-0R-1L-0R
        //2: 1L-0R-0R-1R-0R
        //3: 0L-1R-0R-0R-1R
        //4: 0L-1R-1R-0L-1L
        //5: 0R-1R-1R-0R-1L
        //6: 0L-0R-1L-1R-1L
        //7: 0L-0R-0L-1L-1R
        //8: 0L-0R-0L-1L-0R
        //9: 0L-1L-0L-0L-0R
        static readonly int[] situation = new int[] { 17698, 18211, 19235, 22826, 13674, 
                                                      22892, 15074, 22178, 18082, 17562 };
 
        // Последнее состояние контроллера
        static int controllerState = 0;
 
        // Буферный массив для передачи
        static readonly byte[] bytes = new byte[ 2 ];
 
        //Маска активных узлов
        const int activeMask = 0b_001_001_001_001_001;
 
 
        static void Main( string[] args )
        {
            
            while ( true )
            {
                Console.Write("Номер ситуации: ");
                int idx = Convert.ToInt16( Console.ReadLine() );
                int currval = situation[ idx ];
                DisplayBytes( currval, 15, 3 );
                BridgePorts( currval );
 
                Console.WriteLine();
            }
            
 
 
            static void BridgePorts( int received )
            {
                lock ( bytes )
                {
                    var active = received & activeMask;
                    var listen = received & active << 1 | received & active << 2;
 
                    var currentState = 0;
                    var mask = 0b_11;
                    for ( int i = 0; i < 5; i++ )
                    {
                        currentState |= ( listen >> ( i + 1 ) ) & mask;
                        mask <<= 2;
                    }
 
                    if ( ( currentState ^ controllerState ) > 0 )
                    {
                        bytes[ 0 ] = ( byte ) ( currentState & 255 );
                        bytes[ 1 ] = ( byte ) ( ( currentState >> 8 ) & 255 );
 
                        controllerState = currentState;
 
                        DisplayBytes( bytes[ 0 ] | bytes[ 1 ] << 8, 10, 2 );
                    }
                }
            }
 
            static void DisplayBytes( int toSend, int cnt, int n )
            {
                var str = Convert.ToString( toSend, 2 ).PadLeft( 15, '0' );
                for ( int i = 0; i < cnt; i++ )
                {
                    Console.Write( str[ i ] );
                    if ( ( i + 1 ) % n == 0 ) Console.Write( ' ' );
                }
                Console.Write( '\n' );
            }
 
        }
    }
0
1534 / 542 / 127
Регистрация: 09.01.2018
Сообщений: 1,763
01.09.2021, 11:07
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Откуда такие выводы?
Откуда, откуда. Вы же не знали, что байты контроллера перезаписываются и соотв. сбрасываются при отключении линии. Если бы знали, сразу бы написали что ситуация с "забытым" битом линии попросту невозможна, поскольку вы записываете в нее 00. А вы стали участвовать в обсуждении, говорили, что старались предусмотреть такую ситуацию.

А в тестах вы даже не увидели, что при отключении у вас 1 остается и отправляется на контроллер, доказывали мне, что все работает верно и линия отключается.

То что требования не были понятны с начала, это другое дело. Но я не об этом. Вы должны бы знать что выдаст ваш код на этапе включения отключения, что он делает в принципе. Ну по идее.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.09.2021, 11:16
Лучший ответ Сообщение было отмечено wizard41 как решение

Решение

wizard41, с учётом последних изменений условий, вроде так должно работать:
C#
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
39
40
41
42
43
44
45
46
47
48
49
        // Последнее переданное состояние
        private static int oldSender = 0;
        // Буферный массив для передачи
        private static readonly byte[] bytes = new byte[2];
        //Маска активных узлов
        private const int activeMask = 0b_001_001_001_001_001;
        public static void BridgePorts(int received)
        {
            bool isSend = false;
            lock (bytes)
            {
                // Принятые биты
                //int received = 0b_001_001_001_001_001;
 
                //Получаем активные узлы.
                int active = received & activeMask;
 
                // Маска информационных бит активных узлов.
                int listen = active << 1 | active << 2;
 
                // Новое состояние информационных бит активных узлов.
                // Информационных биты отключенных узлов сброшены в 0.
                int newBits = received & listen;
 
                // Сравнение с состоянием выходов.
                if (oldSender != newBits)
                {
                    oldSender = newBits;
                    // Переформатирование бит
                    int zip = 0;
                    int mask = 0b_11;
                    for (int i = 0; i < 5; i++)
                    {
                        newBits >>= 1;
                        zip |= (newBits & mask);
                        mask <<= 2;
                    }
 
 
 
                    bytes[0] = (byte)(zip & 255);
                    bytes[1] = (byte)((zip >> 8) & 255);
 
                    //SendBit(....., bytes);
                    isSend = true;
                }
            }
            ConsoleWrite(received, bytes, isSend);
        }
C#
1
2
3
4
5
6
7
8
        static void Main(string[] args)
        {
            BridgePorts(0b_011_100_010_100_011); // включаем 1-ю и 5-ю
            BridgePorts(0b_011_100_010_100_010); // отключаем 1-ю
            BridgePorts(0b_011_011_101_101_011); // включаем все линии
            BridgePorts(0b_011_011_100_100_011); // отключаем 2-ю и 3-ю
 
            BridgePorts(0b001_001_001_001_001); // Команда сброса
Консоль:
Code
1
2
3
4
5
011_100_010_100_011     01_00_00_00_01  Отправлено
011_100_010_100_010     01_00_00_00_00  Отправлено
011_011_101_101_011     01_01_10_10_01  Отправлено
011_011_100_100_011     01_01_00_00_01  Отправлено
001_001_001_001_001     00_00_00_00_00  Отправлено
1
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
01.09.2021, 11:18  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Консоль:
Да, все верно.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.09.2021, 11:19
Цитата Сообщение от escoult Посмотреть сообщение
что при отключении у вас 1 остается и отправляется на контроллер
Как это я не увидел?
Я это СПЕЦИАЛЬНО так реализовал, так как такое было условие.
Прочитайте вначале топика.

Без этого условия код даже проще становится.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
01.09.2021, 11:40  [ТС]
Цитата Сообщение от wizard41 Посмотреть сообщение
Опа, вы отправили R-сторону 1-го участка, а включена L (левая). А L-сторону 4-го участка вообще "забыли"...
escoult, сорри, это я накосячил.

Добавлено через 10 минут
Code
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
Номер ситуации: 0
100 010 100 100 010
 
Номер ситуации: 1
100 011 100 100 011
00 00 00 00 01 00 00 01
 
Номер ситуации: 2
100 101 100 100 011
00 00 00 00 10 00 00 01
 
Номер ситуации: 3
101 100 100 101 010
00 00 00 10 00 00 10 00
 
Номер ситуации: 5
101 100 101 101 100
00 00 00 10 00 10 10 00
 
Номер ситуации: 6
011 101 011 100 010
00 00 00 01 10 01 00 00
 
Номер ситуации: 0
100 010 100 100 010
00 00 00 00 00 00 00 00
 
Номер ситуации:
Да, четко.
0
1534 / 542 / 127
Регистрация: 09.01.2018
Сообщений: 1,763
01.09.2021, 11:42
Цитата Сообщение от wizard41 Посмотреть сообщение
сорри, это я накосячил.

На всякий случай, ниже результаты по вашим кейсам:
Пустая строка означает, что ничего не отправили.
Code
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
Test case 0 - [17698]
100 010 100 100 010
 
Test case 1 - [18211]
100 011 100 100 011
00  01  00  00  01
 
Test case 2 - [19235]
100 101 100 100 011
00  10  00  00  01
 
Test case 3 - [22826]
101 100 100 101 010
10  00  00  10  00
 
Test case 4 - [13674]
011 010 101 101 010
01  00  10  10  00
 
Test case 5 - [22892]
101 100 101 101 100
10  00  10  10  00
 
Test case 6 - [15074]
011 101 011 100 010
01  10  01  00  00
 
Test case 7 - [22178]
101 011 010 100 010
10  01  00  00  00
 
Test case 8 - [18082]
100 011 010 100 010
00  01  00  00  00
 
Test case 9 - [17562]
100 010 010 011 010
00  00  00  01  00
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
01.09.2021, 14:37  [ТС]
Цитата Сообщение от escoult Посмотреть сообщение
Пустая строка означает, что ничего не отправили.
Ну это я как-то понял
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.09.2021, 14:37

Изменить рандомный бит в байте
Доброго времени суток. Подскажите пожалуйста, как сменить рендомный бит в считанном из файла байте? На другом языке обычно строка - это...

Порядок байт в слове и бит в байте
читал эту требуются пояснения. A B C D - адреса в них число 128 BE A B C D ...

Написать функцию, меняющую порядок бит в байте
написать функцию, меняющую порядок бит в байте. заранее спасибо

последовательность инструкций для обнуления трех старших бит регистра DH, без изменения остальных бит
Напишите последовательность инструкций для обнуления трех старших бит регистра DH, без изменения остальных бит; результат сохраните в...

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


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

Или воспользуйтесь поиском по форуму:
129
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru