Предполагам голяма част от вас знаят, че информацията в компютрите се съхранява като последователност от нули и единици, т.е. така наречените битове. Ето защо операциите, свързани пряко с тях, са едни от най-бързо осъществяваните от компютърните програми. Известно е и, че работата с някои данни като например IP адрес са пряко свързани с разбирането на тези побитови пресмятания. Друг случай, в който се налага да боравим с побитови преобразования, е при оптимизация на сложни и обемни математически изчисления, извършвани от компютър.
Задачата, която ще разгледаме, показва как може да се разменят битовете на число в uint формат (32-битово положително число) в езика C# като поставяме ограничение да няма припокриване на първата и втората двойка битове. Тази задача беше част от разгледания материал на курса по C# Fundamentals в академията на Телерик.
Методът BitsExchanger изисква като аргументи: числото, на което ще разменяме битовете (number), номера на началния бит на двете последователности от битове за разменяне (p и q) и броя битове след първия на тези две последователности (range). В началото проверяваме дали са изпълнени следните условия: номерът на бита да не излиза от 32-битовия формат и евентуално да няма препокриване на разменяните битове. Ако се въведе такава невалидна информация, функцията извежда ArgumentExceprion.
Задачата, която ще разгледаме, показва как може да се разменят битовете на число в uint формат (32-битово положително число) в езика C# като поставяме ограничение да няма припокриване на първата и втората двойка битове. Тази задача беше част от разгледания материал на курса по C# Fundamentals в академията на Телерик.
Програмен код:
public static uint BitsExchanger(uint number, byte p, byte q, byte range) { if ((p + range) > 31 || (q + range) > 31 || Math.Abs(p - q) <= range) { throw new ArgumentException(); } uint maskP = new uint(); uint maskQ = new uint(); for (int i = 0; i <= range; i++) { maskP = maskP | (uint)(1 << (p + i)); maskQ = maskQ | (uint)(1 << (q + i)); } uint subBitsP = number & maskP; uint subBitsQ = number & maskQ; number = (~maskQ & number) | (subBitsP << q - p); number = (~maskP & number) | (subBitsQ >> q - p); return number; }
Обяснение:
Методът BitsExchanger изисква като аргументи: числото, на което ще разменяме битовете (number), номера на началния бит на двете последователности от битове за разменяне (p и q) и броя битове след първия на тези две последователности (range). В началото проверяваме дали са изпълнени следните условия: номерът на бита да не излиза от 32-битовия формат и евентуално да няма препокриване на разменяните битове. Ако се въведе такава невалидна информация, функцията извежда ArgumentExceprion.
За самите преобразувания използваме две маски: maskP с единични битове на позициите от p до p+k и
maskQ с единични битове на позициите
от q до q+range. Маските
се създават чрез използване на цикъл от 0
до range. В него се извършва операция побитово или ( | ) на маската с преместен с оператора << единичен бит на необходимите позиции. Чрез тях и операцията побитово и ( & ) извличаме първата последователност от битове (от p до p+range) в променлива subBitsP, а втората последователност от битове (от q до q+range) в друга променлива subBitsQ. Операцията & всъщност занулява всички други битове, освен означените от маската като единици, които си запазват стойността.
За битове от p до p+range чрез използване на отрицанието на маската на maskQ (т.е. зануляване на битове от q до q+range) и използване на | (побитово или) с променливата subBitsP, преместената с q-p позиции чрез оператора <<. осъществяваме заменяне на първата поредица (от p до p+range) от битове с позициите на втората (от q до q+range). Правим подобна операция, но в обратната посока за преместването на втората последователност от битове.
За битове от p до p+range чрез използване на отрицанието на маската на maskQ (т.е. зануляване на битове от q до q+range) и използване на | (побитово или) с променливата subBitsP, преместената с q-p позиции чрез оператора <<. осъществяваме заменяне на първата поредица (от p до p+range) от битове с позициите на втората (от q до q+range). Правим подобна операция, но в обратната посока за преместването на втората последователност от битове.
Няма коментари:
Публикуване на коментар