| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Оперирование отдельными байтами переменной |
| Автор: Semion 1.9.2002, 21:36 |
| Мне нужен удобный способ доступа к определённому байту некоторой переменной. Можно, конечно, написать алгоритм, раскладывающий десятичное число в двоичное, меняющий байт и наоборот. Но это громоздко и неэффективно. Наверняка, для этого существуют встроенные удобные функции. Не подскажете? |
| Автор: Semion 1.9.2002, 21:38 |
| Не байтами, а битами. Простите за ошибку. |
| Автор: Baa 1.9.2002, 22:23 |
| А чем тебя обычные сдвиги не устроили? рассмотрим байт как двоичное число (переводить никуда ничего не надо) 11001100 И вот тебе надо выцепить 4 средних бита....Что для этого надо? test = (11001100 & 00111100) >> 2; int test = (a & 0x3C) >> 2; Можно написать макрос, который будет вытаскивать определенный бит по маске. Ну и выставить их тож не сложно... int test = (test & 0xC3) | (a << 2); |
| Автор: Semion 1.9.2002, 23:25 |
| Я, просто, раньше не пользовался операторами сдвига (<< >>). Теперь ясно. Предполагаю, что, анологично, можно заменять биты. Например, если в переменной Value нужно присвоить 5 биту справа единицу, то нужно проверить, обнулён ли он. Если да, то сместить на 5 битов вправо, инкрементировать Value, затем сместить на 5 битов влево. Аналогично, декрементируя, можно обнулять любой бит. Спасибо за совет. |
| Автор: Semion 2.9.2002, 02:18 |
| Нет, такое изменение невозможно, так как биты смещаются не по кругу. Смещённые биты просто стираются. Нужно проверить, что в n-ном бите справа. Если 0, а нужен 1, то нужно Value += 2^n. (Если 1, а нужен 0, то Value -= 2^n.) |
| Автор: Fantasist 2.9.2002, 04:00 | ||
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 2.9.2002, 04:33 | ||
Если хочешь, чтобы биты смещались покругу, то используй ассемблер (rol, ror) Ток на самом деле - это лишнее. Просто надо хорошо понимать булевые операции. 11001100 | 11001100 & | ^ 10101010 | 10101010 = | = 10001000 | 01100110 ------------------------------------------- 11001100 | 11001100 | | ~ 10101010 | =00110011 = | 11101110 | |
| Автор: Baa 2.9.2002, 04:36 |
| 2Fantasist: Зачем обнулять xor'ом если можно обнулить and'ом с нулями (притом так можно обнулить только часть байта(если нужно выставить что-то в середине)). |
| Автор: Fantasist 2.9.2002, 04:56 | ||
Это как это? Если у меня положим переменная в одни байт: 01101001 и хочу я обнулить 4 бит справа. Я думаю делать это так: 01101001 & 11110111 Как мне теперь, как мне получить такое число (11110111) если мне известен только номер бита, куда я хочу поставить ноль? Проще всего было бы: !(1<<bit_no), но С++ этого не поддерживает. |
| Автор: Baa 2.9.2002, 09:01 |
| Чего-то я вообще не пойму... Надо обнулить 4 бита справа? 11110111 & 11110000 = 11110000 Вот и обнулили. А зачем было обнулять все, если ноль надо поставить в определенное место? Тогда и надо было обнулять то место, где ноль должен быть. А так? ~(1<<bit_no) |
| Автор: Fantasist 2.9.2002, 10:12 | ||
Ага. Правильно. То-то я и думаю, что не может быть, чтобы в С++ битого отрицания не было. Значит переписываем так: #define ClearBit(target,bit_no) ((target)=(target)&(~(1<<(bit_no)))) Еще реккомендую присмотрется к классу bitset<N> из стандартной бибиотеки, где N - количество бит. |