Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

Копирование бита - C++

26.06.2012, 06:13. Просмотров 1968. Ответов 23
Метки нет (Все метки)

Надо упростить и оптимизировать строку
C++
1
*p=((*p&0x80)>>8)|(*p&0x80);
. Задача - скопировать (не переместить) старший бит байта в младший бит того же байта.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2012, 06:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Копирование бита (C++):

Создать 2 переменные, одна из которых хранит 2 старших бита исходного числа, другая 2 младших бита этого числа - C++
Дано число. Создать 2 переменные, одна из которых хранит 2 старших бита исходного числа, другая 2 младших бита этого числа. код частично...

Извлечь 3 бита числа A, начиная со второго и вставить их в число B, начиная с первого бита - C++
Ввести целое A. Извлечь 3 бита числа A, начиная со второго и вставить их в число B, начиная с ервогоп бита. B=1A05h.

Установка бита - C++
Дано целое число A и целое число k. Выведите число, которое получается из числа A установкой значения k-го бита равному 1.

Проверка бита - C++
Всем привет. Хотел спросить знающих людей, как можно проверить бит в байте. То есть, допустим, есть unsigned char "01010101". Какими...

Обработка бита - C++
Название Размерность Тип N 16 вход M 4 вх P ...

Обработка бита - C++
На входе даны два 8-х разарядных числа IN_0, IN_1. Если на пятом месте в IN_0 стоит 0, то поменять знак числа IN_1,(и вывести...

23
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 07:14 #2
Цитата Сообщение от taras atavin Посмотреть сообщение
и оптимизировать строку
Начнём с того, что твой код работает не правильно. В нём содержится целых ДВЕ ошибки.
1. (*p&0x80)>>8) всегда равно нулю (для байтов)
2. Для числа 0х1 копирование старшего бита должно "обнулить" число, но у тебя младший бит по прежнему останется единицей.

Так что ты для начала научись писать ПРАВИЛЬНО работающие функции, а потом уже думай над их оптимизацией.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 08:01  [ТС] #3
Забыл, что с ноля. Старший то седьмой, а я пытался двинуть восьмой.
C++
1
*p=((*p&0x80)>>7)|(*p&0x80);
.

Добавлено через 1 минуту
Но, что самое смешное, с такими ошибками работал код, зависимый от этого. Только мог глючить при удержании.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 08:14 #4
Ошибку "номер 2" теперь исправляй. Сейчас у тебя не копирование старшего бита, а установка единицы. Если старший бит нулевой, но на младшем это не сказывается. Чини дальше.)
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 09:23  [ТС] #5
Было 0b1000 0000, *p&0x80=0b1000 0000, (*p&0x80)>>7=0b0000 0001, ((*p&0x80)>>7)|(*p&0x80)=0b1000 0001, стало 0b1000 0001, теперь было 0b0000 0001, *p&0x80=0b0000 0000, (*p&0x80)>>7=0b0000 0000, ((*p&0x80)>>7)|(*p&0x80)=0b0000 0000, стало 0b0000 0001. Ошибка теперь у тебя, там "побитовое И", оно учитывает оба операнда. И залипание/отлипание теперь работает без глюков, кнопки отлипают как при повторном нажатии их самих, так и при нажатии противоположных им. И две кнопки не залипают в принципе, как и задумано. Две залипают только при повторном нажатии их самих, так тоже задумано. На удержание реагируют только не залипающие. Так тоже задумано.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 09:38 #6
Цитата Сообщение от taras atavin Посмотреть сообщение
Ошибка теперь у тебя
Цитата Сообщение от taras atavin Посмотреть сообщение
Задача - скопировать
Ты ведь знаешь, что такое копирование?
было 0х1
(0b00000001 & 0x80)>>7 = 0
0 | 1 = 1
Т.е. после "копирования" старшего бита в младший, значение младшего не поменялось, хотя должно стать нулём.
То, что реализовано у тебя, это ни разу не копирование. Если написать более явный код, то во как выглядит твой алгоритм:
C++
1
2
3
BYTE p = ...;
if( p & 0x80 )
   p |= 1; // или p += 1;
Как видишь, это совсем не то же самое, что КОПИРОВАНИЕ старшего бита, для которого код выглядит так
C++
1
2
3
4
5
BYTE p = ...;
if( p & 0x80 )
    p |= 1;
else
   p &= 0xFE; // обнуляю младший бит
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 09:50  [ТС] #7
Цитата Сообщение от Deviaphan Посмотреть сообщение
Ты ведь знаешь, что такое копирование?
было 0х1
(0b00000001 & 0x80)>>7 = 0
0 | 1 = 1
В старшем бите в этом примере был 0, он и скопирован.

Добавлено через 3 минуты
Цитата Сообщение от Deviaphan Посмотреть сообщение
0 | 1 = 1
Т.е. после "копирования" старшего бита в младший, значение младшего не поменялось, хотя должно стать нулём.
чего это вдруг? 0|0, а не 0|1 Смотри внимательно правый операнд оператора "побитовое ИЛИ". Там не исходное число, а снова операция, отбрасывающая все биты, кроме старшего. Коды такие: 0x00 - давно отпущена, или ни когда не нажималась, 0x01 - только что отпущена, 0x80 - только что нажата, 0x81 - давно нажата. То есть оба бита имеют самостоятельные значения: старший - флаг текущего состояния кнопки, младший - флаг предыдущего её состояния.

Добавлено через 6 минут
Цитата Сообщение от Deviaphan Посмотреть сообщение
p &= 0xFE; // обнуляю младший бит
Есть одна особенность: байт - только код, фактическая разрядность хранимой величины два бита, а не восемь, просто код предусматривает дополнение до байта нолями в середине.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 09:55 #8
Цитата Сообщение от taras atavin Посмотреть сообщение
Смотри на внимательно правый операнд оператора "побитовое ИЛИ".
Я не про "ИЛИ", а про слово КОПИРОВАНИЕ говорю. Ты выполняешь логическое сложение, а не копирование. КОПИРОВАНИЕ это когда берёшь ноль и записываешь ноль. Т.е. результат равен оригиналу. Всё прочее НЕ копирование. Давай говорить не в терминах битов, а в терминах чисел.
Было a = 0, b = 1;
Выполняем КОПИРОВАНИЕ: b = a; Вопрос, чему равно b?
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 10:49  [ТС] #9
Я выполняю логическое сложение сдвинутого и не сдвинутого вариантов старшего бита. Сдвинутый - это то, что надо записать в младший, а не сдвинутый - это то, что надо сохранить в старшем. Код уже отлажен и протестирован на машине, надо только оптимизировать.

Добавлено через 5 минут
Будет ли быстрее такой код:
C++
1
2
3
4
5
6
7
struct T2Flags
{
 int Current:1;
 int Zero:6;
 int Old:1;
};
((T2Flags *)p)->Old=((T2Flags *)p)->Current;
?

Добавлено через 46 минут
Цитата Сообщение от Deviaphan Посмотреть сообщение
Давай говорить не в терминах битов, а в терминах чисел.
Давай
Цитата Сообщение от Deviaphan Посмотреть сообщение
Было a = 0, b = 1;
Выполняем КОПИРОВАНИЕ: b = a; Вопрос, чему равно b?
0.Было a = 1, b = 0;
Выполняем КОПИРОВАНИЕ: b = a; внимание вопрос: чему равно a. Если убрать "побитовое ИЛИ", то нолю, то есть вместо копирования получим перенос.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 15:51 #10
Цитата Сообщение от taras atavin Посмотреть сообщение
Если убрать "побитовое ИЛИ
Банальная логика подсказывает, что после копирования источник значения (бит, из которого копируется) и приёмник (бит, в который копируют) становятся равны. Эквивалентность этих величин определяет термин "копирование". Т.к. этому "явлению" уже тысячи лет, предлагаю данный момент забыть и закрыть.

Цитата Сообщение от taras atavin Посмотреть сообщение
a = 1, b = 0;
Выполняем КОПИРОВАНИЕ: b = a;
а не изменится, т.к. она справа. Независимо от операции.) А b станет равно 1.

Цитата Сообщение от taras atavin Посмотреть сообщение
Будет ли быстрее такой код:
Нет, не будет. "Ручная" работа с битами будет эффективнее. В лучшем случае, компилятор сможет "написать" такой же код, как и при маскировании битов.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 16:49  [ТС] #11
Цитата Сообщение от Deviaphan Посмотреть сообщение
Банальная логика подсказывает, что после копирования источник значения (бит, из которого копируется) и приёмник (бит, в который копируют) становятся равны. Эквивалентность этих величин определяет термин "копирование". Т.к. этому "явлению" уже тысячи лет,....
вот только ты этого не знаешь до сих пор и приходится объяснять.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 16:51 #12
Цитата Сообщение от taras atavin Посмотреть сообщение
вот только ты этого не знаешь до сих пор и приходится объяснять.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 16:55  [ТС] #13
Цитата Сообщение от Deviaphan Посмотреть сообщение
а не изменится, т.к. она справа. Независимо от операции.)
Ты забываешь, что это части одного и того же байта. c=a*2+b (c состоит из цифр a и b), и a=1, b=0, тогда c=2, с&0b10 = 0b10=2, (c&0b10)>>2=0b01=1, выполняем
C++
1
c=(c&0b10)>>2;
, получаем c=1, при a*2+b, стало a=0, а b =1. (c&0b10)>>2 - это новое b, но присваиваю то я не b, а c, а это сумма. Ну так я и пишу
C++
1
c=(c&0b10)>>2+(c&0b10);
, где (c&0b10) - это a.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
26.06.2012, 17:03 #14
Цитата Сообщение от taras atavin Посмотреть сообщение
Ты забываешь, что это части одного и того же байта.
Я приводил пример с независимыми a и b. Почему с независимыми? Потому что бит 7 и бит 0 не зависят друг от друга.
Давай попроще, с двумя битами нарисую.
Число b01
Как выполнить КОПИРОВАНИЕ?
Берём значение бита один и копируем его в бит ноль. При этом бит ноль становится таким же, как и бит один. Потому что, после копирования приёмник и источник становятся равны. Т.е. после копирования число будет b00. Любая другая операция, после которой число будет другим копирование НЕ является.
Блин, мне уже не смешно. Пойду поем.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2012, 17:21  [ТС] #15
Цитата Сообщение от Deviaphan Посмотреть сообщение
Я приводил пример с независимыми a и b. Почему с независимыми? Потому что бит 7 и бит 0 не зависят друг от друга.
Давай попроще, с двумя битами нарисую.
Число b01
Как выполнить КОПИРОВАНИЕ?
Берём значение бита один и копируем его в бит ноль. При этом бит ноль становится таким же, как и бит один. Потому что, после копирования приёмник и источник становятся равны. Т.е. после копирования число будет b00. Любая другая операция, после которой число будет другим копирование НЕ является.
Блин, мне уже не смешно. Пойду поем.
Берём число 123 и копируем старшую цифру в младшукю. Получим 121. Цифры после копирования равны друг другу, но число целиком неизбежно изменится, так как выполнена операция над цифрами одного и того же числа, которые не были равны, но стали равны. Так вот, запомни: биты - не числа, а цифры. Всегда. А число - это минимум байт. Задача скопировать одну цифру байта в другую цифру того же байта. Если они не были равны до копирования, то он должен измениться. А если число из 123 стало 21, то во-первых оно тоже изменилось, а во-вторых это не копирование, а перенос. Если же цифры уже равны, то операция избыточна.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.06.2012, 17:21
Привет! Вот еще темы с ответами:

Замена бита единицей - C++
Здравствуйте, помогите пожалуйста решить задачку. Нужно: ввести последовательность из 8 целых чисел. В каждом втором числе заменить (...

Наличие бита в байте - C++
Подскажите, правильна ли реализация проверки наличия бита в байте #define MARK 0x02 .. if (dataRead & MARK) { ...

Как проверить 2 бита? - C++
BorlandC++3.0 MS-DOS, надо проверить 5й бит равен 1, а 6й бит = 0, не получается их проверить в одном IF, если проверяю по отдельности, то...

Проверка бита на единицу - C++
Подскажите, корректно ли такое сравнение if((paramData &= 0x80) == 1) // проверка на наличие единицы(1) в 8-ом бите данного байта длины...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
26.06.2012, 17:21
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru