it-place.net > Уроци > C-Cplusplus
Не сте регистриран! Регистрирайте се БЕЗПЛАТНО, за да използвате услугите на сайта!

   Рубрики
 
 
 
 

 Форуми
» SEO и оптимизация
» Всичко за PHP и Perl
» Всичко за C, C++ и .NET
» Всичко за Java и JSP
» Всичко за SQL и MySQL
» Всичко за XHTML и CSS
» Презентация на сайтове
 Техники за побитова манипулация и приложения
  1. Причини за прилагане на побитова манипулация
  2. Битови маски
  3. Единични битови маски
  4. Как да приложим всичко това на практика
  5. Отделяне на няколко стойности в една променлива
blowfish
     
Автор  blowfish (19.08.2007 13:03)  съобщение до автора
Погледнат  10223 пъти  добави към любими
Оценка  добави коментар
Гласове  2  изпрати на приятел
Коментари  (4)  абонирай се за C-Cplusplus
    Страница 1 / 5

 



Ако ви е омръзнало да четете от книгите какво е побитов AND, XOR, OR или ляво/дясно изместване, а в същото време не сте сигурни как и за какво можете да ползвате на практика побитови операции, то тази статия е точно за вас. Тук няма да изброяваме побитовите оператори или да показваме формалните дефиниции на побитовите операции, а ще се съсредоточим върху някои основни техники за побитова манипулация и приложенията им. Истина е, че повечето книги, които са ми попадали само загатват темата, подминавайки истинската същност, без да показват на читателя нищо повече от списък с побитови оператори и формалната дефиниция на побитовите операции. Това оставя едно впечатление у начинаещите, че едва ли не побитовите операции са “тъмна индия”, без реално разбиране защо и как трябва да се ползват.

Причини за прилагане на побитова манипулация

Главната първопричина е стремежа да се оползотвори максимално пространството във всеки байт. Друго нещо е и факта, че всяка побитова операция съответства на конкретна процесорна инструкция, а това прави оперирането върху групи от битове изключително бързо. В криптографията пък доста често се използва свойството на XOR операцията за обратимост.

Случвало ли ви се е например, да имате променлива от тип int, която ще ползвате със стойности само в ограничен интервал, например от 0 до 500? Най-голямото число в интервала, 500, в двоична форма се представя като 111110100. Следователно вие няма да използвате повече от 9 бита, а разполагате с цели 32. Така вие похабявате 23 бита, които винаги ще бъдат изключени, и ще заемат място в паметта. Как бихте се справили с този проблем?

Компютърните архитектури не ви позволяват да имате променливи с дължина в битове не-кратна на 8, поради простия факт, че е прието един байт да е 8 бита, и байта е неделима единица от гледна точка на паметта. Не случайно типа bool е една абстракция и в езика C той не съществува. С други думи, възможно е да имате променливи с дължина от 8, 16, 24, 32, 40 бита и т.н., но не и от 9 бита в нашия случай. Дори и да изберем променлива short която е 16 бита, отново ще има неоползотворено място. Решението е да използваме останалото място за да отделим други стойности.

За да можем да “разцепим” нашата променлива на битове и да четем/записваме статуса на всеки един бит, а също така и на групи от битове вътре в променливата, се налага да ползваме побитови операции.



  Следваща страница >> 


Ключови думи: C++ побитова манипулация битови маски маскиране двоична форма


Още уроци от тази рубрика


 
  • Подобни теми от myLinks
 

 За автора: blowfish  
Благовест Буюклиев има 10+ години опит с програмирането на C/C++, 7+ години опит с PHP и обширни познания в съвременните Web технологии. Като програмист и проектант на софтуер най-много цени добре проектирания, оформен, документиран, логически издържан и ефективен код. Работил е за фирми в България и чужбина, последната му страст е проектиране и имплементация на TCP сървърни приложения за Linux. Чрез статииите си в it-place.net би искал да предаде част от знанието и опита си на максимално широк кръг хора в България.
   
 1 посетител чете този урок (0 потребители и 1 гост)  
Активни потребители: ---
   
  

Еmail  
 

Е, да, с макроси и константи е съвсем различно, но интересът си остава преди всичко в манипулирането на определени типове данни като пиксели, компресирани данни и т.н. Използването за представяне на цели числа, с цел да пестим място наистина не ми се струва, че има голям интерес с оглед влошената четимост на кода.Трябва наистина да си в много крайна ситуация на някаква система с примерно 1-2Ко памет, за да имаш реален интерес от това 

  SOMNIVM на 08.10.2007 01:40

SOMNIVM, не съм съгласен.

Кодът от последната част представя една много добре генерализирана и опростена схема за манипулация на групи от битове в битвектор. Една тривиална задача като извличане/задаване на RGB стойности от 24-битови пиксели например би могла да се свърши доста елегантно (и ефективно и разбираемо в същото време!) по начина който съм показал. Аз в реална програма бих използвал двете функции с единствената промяна, че ще ги направя макроси за да премахна overhead-а при извикване и копиране на параметрите. И не виждам какво "извъртяно" ще има в кода когато ползвам 2-3 процесорни инструкции за една манипулация. В този туториал ги направих като функции за да е по-разбираемо за начинаещите. Ето ги и като макроси, съвсем удобни за използване в реална програма:

CODE
1
2
3
4
5
#define SET(bitvector, mask, offset, value) \
 
(((bitvector) & ~(mask)) | ((value) << (offset)))

#define GET(bitvector, mask, offset) \
 
(((bitvector) & (mask)) >> (offset))

Пример:

CODE
1
2
3
4
register unsigned pixel = 0xAABBCCDD;

pixel = SET(pixel, MASK_GREEN, OFFSET_GREEN, 0xEE);
pixel = GET(pixel, MASK_GREEN, OFFSET_GREEN);

Сам виждаш, че при нормално извикване имаш референция само към една променлива и всичко останало са константи, операциите между които се сдъвкват още от компилатора.

Кодът служещ ти да за управление на битвектора ти "изяжда" спестеното място и прави програмата изключително "извъртяна".

По-просто, по-бързо или по-елегантно от това здраве му кажи Има още хиляди примери където може да се ползва, но това беше първото за което се сетих.

  blowfish на 25.09.2007 02:57

Тъй като октетът е най-малката адресируема единица в паметта, побитовото представяне на променливи не е от кой знае какъв интерес. Кодът служещ ти да за управление на битвектора ти "изяжда" спестеното място и прави програмата изключително "извъртяна". Аз такава програма никога не бих написал поне    Иначе тези оператори имат приложения и ти си ги посочил. Мисля в тази връзка да пусна един туториал за компресията като ми се намери малко повечко свободно време скоро.
Поздрави!

  SOMNIVM на 24.09.2007 20:20

  Чудесно :)))

  Miro на 22.09.2007 17:09

 

 
  • Интересно от Софтуер
 



IT-PLACE.NET © 2004 - 2008