![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Semion |
|
|||
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 31.8.2002 Репутация: нет Всего: нет |
Мне нужен удобный способ доступа к определённому байту некоторой переменной. Можно, конечно, написать алгоритм, раскладывающий десятичное число в двоичное, меняющий байт и наоборот. Но это громоздко и неэффективно. Наверняка, для этого существуют встроенные удобные функции. Не подскажете?
![]() |
|||
|
||||
Semion |
|
|||
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 31.8.2002 Репутация: нет Всего: нет |
Не байтами, а битами. Простите за ошибку.
![]() |
|||
|
||||
Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 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 |
|||
|
||||
Semion |
|
|||
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 31.8.2002 Репутация: нет Всего: нет |
Я, просто, раньше не пользовался операторами сдвига (<< >>). Теперь ясно. Предполагаю, что, анологично, можно заменять биты. Например, если в переменной Value нужно присвоить 5 биту справа единицу, то нужно проверить, обнулён ли он. Если да, то сместить на 5 битов вправо, инкрементировать Value, затем сместить на 5 битов влево. Аналогично, декрементируя, можно обнулять любой бит. Спасибо за совет.
![]() |
|||
|
||||
Semion |
|
|||
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 31.8.2002 Репутация: нет Всего: нет |
Нет, такое изменение невозможно, так как биты смещаются не по кругу. Смещённые биты просто стираются. Нужно проверить, что в n-ном бите справа. Если 0, а нужен 1, то нужно Value += 2^n. (Если 1, а нужен 0, то Value -= 2^n.)
|
|||
|
||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
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, но это решайте сами. Может что получше придумать можно. -------------------- Волны гасят ветер... |
|||
|
||||
Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: 8 Всего: 12 |
Если хочешь, чтобы биты смещались покругу, то используй ассемблер (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 |
|||
|
||||
Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: 8 Всего: 12 |
2Fantasist:
Зачем обнулять xor'ом если можно обнулить and'ом с нулями (притом так можно обнулить только часть байта(если нужно выставить что-то в середине)). -------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Это как это? Если у меня положим переменная в одни байт: 01101001 и хочу я обнулить 4 бит справа. Я думаю делать это так: 01101001 & 11110111 Как мне теперь, как мне получить такое число (11110111) если мне известен только номер бита, куда я хочу поставить ноль? Проще всего было бы: !(1<<bit_no), но С++ этого не поддерживает. -------------------- Волны гасят ветер... |
|||
|
||||
Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 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 |
|||
|
||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Ага. Правильно. То-то я и думаю, что не может быть, чтобы в С++ битого отрицания не было. Значит переписываем так: #define ClearBit(target,bit_no) ((target)=(target)&(~(1<<(bit_no)))) Еще реккомендую присмотрется к классу bitset<N> из стандартной бибиотеки, где N - количество бит. -------------------- Волны гасят ветер... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |