Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оперирование отдельными байтами переменной, Как удобней? 
:(
    Опции темы
Semion
Дата 1.9.2002, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 31.8.2002

Репутация: нет
Всего: нет



Мне нужен удобный способ доступа к определённому байту некоторой переменной. Можно, конечно, написать алгоритм, раскладывающий десятичное число в двоичное, меняющий байт и наоборот. Но это громоздко и неэффективно. Наверняка, для этого существуют встроенные удобные функции. Не подскажете?  :notify
PM MAIL   Вверх
Semion
Дата 1.9.2002, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 31.8.2002

Репутация: нет
Всего: нет



Не байтами, а битами. Простите за ошибку. :(
PM MAIL   Вверх
Baa
Дата 1.9.2002, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



А чем тебя обычные сдвиги не устроили?
рассмотрим байт как двоичное число (переводить никуда ничего не надо)
11001100
И вот тебе надо выцепить 4 средних бита....Что для этого надо?
test = (11001100 & 00111100) >> 2;
int test = (a & 0x3C) >> 2;
Можно написать макрос, который будет вытаскивать определенный бит по маске.
Ну и выставить их тож не сложно...
int test = (test & 0xC3) | (a << 2);




--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Semion
Дата 1.9.2002, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 31.8.2002

Репутация: нет
Всего: нет



Я, просто, раньше не пользовался операторами сдвига (<< >>). Теперь ясно. Предполагаю, что, анологично, можно заменять биты. Например, если в переменной Value нужно присвоить 5 биту справа единицу, то нужно проверить, обнулён ли он. Если да, то  сместить на 5 битов вправо, инкрементировать Value, затем сместить на 5 битов влево. Аналогично, декрементируя, можно обнулять любой бит. Спасибо за совет. :)
PM MAIL   Вверх
Semion
Дата 2.9.2002, 02:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 31.8.2002

Репутация: нет
Всего: нет



Нет, такое изменение невозможно, так как биты смещаются не по кругу. Смещённые биты просто стираются. Нужно проверить, что в n-ном бите справа. Если 0, а нужен 1, то нужно Value += 2^n. (Если 1, а нужен 0, то Value -= 2^n.)
PM MAIL   Вверх
Fantasist
Дата 2.9.2002, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
если в переменной Value нужно присвоить 5 биту справа единицу, то нужно...


Value=Value|(1<<4); // операция OR - битовое сложение

Точно так же обнулить:

Value=Value&((1<<4)^1111111111111111);
//тут слегка хитрее - в С++ почему-то нет битового NOT поэтому я написал XOR с рядом едениц.

То есть, как уже Baa сказал лучше написать функции или определить макросы типа:
#define SetBit(target,bit_no) ((target)=(target)|(1<<(bit_no)))
#define ClearBit(target,bit_no) ((target)=(target)&((1<<(bit_no))^1111111111111111))
#define HaveBit(target,bit_no) (bool((target)&(1<<(bit_no))))

P.S. Очевидно, что ClearBit не будет работать, если bit_no>15. Конечно, можно написать, ^0xFFFF, но это решайте сами. Может что получше придумать можно.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Baa
Дата 2.9.2002, 04:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Цитата(Semion @ 01.9.2002, 19:18)
Нет, такое изменение невозможно, так как биты смещаются не по кругу.

Если хочешь, чтобы биты смещались покругу, то используй ассемблер (rol, ror)
Ток на самом деле - это лишнее.
Просто надо хорошо понимать булевые операции.
11001100 |  11001100
&            |  ^
10101010 |  10101010
=            |  =
10001000 |  01100110
-------------------------------------------
11001100 |  11001100
|            |  ~
10101010 |  =00110011
=            |
11101110 |


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Baa
Дата 2.9.2002, 04:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



2Fantasist:
Зачем обнулять xor'ом если можно обнулить and'ом с нулями (притом так можно обнулить только часть байта(если нужно выставить что-то в середине)).


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Fantasist
Дата 2.9.2002, 04:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Зачем обнулять xor'ом если можно обнулить and'ом с нулями


Это как это? Если у меня положим переменная в одни байт:
01101001
и хочу я обнулить 4 бит справа. Я думаю делать это так:
01101001
&
11110111

Как мне теперь, как мне получить такое число (11110111) если мне известен только номер бита, куда я хочу поставить ноль? Проще всего было бы:
!(1<<bit_no), но С++ этого не поддерживает.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Baa
Дата 2.9.2002, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



Чего-то я вообще не пойму...
Надо обнулить 4 бита справа?
11110111
&
11110000
=
11110000
Вот и обнулили.
А зачем было обнулять все, если ноль надо поставить в определенное место?
Тогда и надо было обнулять то место, где ноль должен быть.
А так?
~(1<<bit_no)


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Fantasist
Дата 2.9.2002, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
~(1<<bit_no)


Ага. Правильно. То-то я и думаю, что не может быть, чтобы в С++ битого отрицания не было. Значит переписываем так:

#define ClearBit(target,bit_no) ((target)=(target)&(~(1<<(bit_no))))

Еще реккомендую присмотрется к классу bitset<N> из стандартной бибиотеки, где N - количество бит.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0734 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.