Чи доводилося вам коли-небудь використовувати зсув бітів у реальних проектах?


83

Чи доводилося вам коли-небудь використовувати зсув бітів у реальних програмових проектах? У більшості (якщо не у всіх) мовах високого рівня є оператори зсуву, але коли вам насправді доведеться їх використовувати?

Відповіді:


58

Я все ще пишу код для систем, які не мають апаратної підтримки з плаваючою комою. У цих системах вам потрібна зміна бітів майже для всієї вашої арифметики.

Також вам потрібні зміни для генерування хешів. Поліноміальна арифметика (CRC, коди Ріда-Соломона є основними додатками) або також використовує зрушення.

Однак зміни просто використовуються, тому що вони зручні і виражають саме те, що задумав письменник. Ви можете емулювати всі бітові зсуви множенням, якщо хочете, але це було б складніше писати, менше читати, а часом і повільніше.

Компілятори виявляють випадки, коли множення може бути зведене до зсуву.


37

Так, я використовував їх багато разів. Перетворення бітів важливо на вбудованому обладнанні, де бітові маски дуже поширені. Це також важливо при програмуванні ігор, коли вам потрібен кожен останній виступ.

Редагувати: Крім того, я багато використовую їх для маніпулювання растровими зображеннями, наприклад, для зміни глибини кольору або для перетворення RGB <-> BGR.


Відряджений. Я роблю багато вбудованого програмування, і зсув бітів є звичайною операцією.
e.James

Перетворення RGB <-> BGR тут.
Ніл Н

25
  • Створення приємних значень прапорів для перерахувань (а не введення вручну 1, 2, 4 ...)
  • Розпакування даних із бітових полів (багато мережевих протоколів їх використовують)
  • Обхід Z-кривої
  • Хакі продуктивності

І я не можу згадати багато випадків, коли їх використовують. Зазвичай все інше - є якась конкретна проблема, і виявляється, що використання бітових операцій дасть найкращі результати (як правило, з точки зору продуктивності - часу та / або простору).


Він може знадобитися для зберігання, наприклад, двох shorts в одному intполі eger у стані сеансу в ASP.net без накладних витрат на зчитування та блокування сеансу для зчитування двох окремих значень. Також зберігається накладна пам'ять на збереження двох значень у сеансі.
David d C e Freitas

15

Я використовую їх постійно, коли транспоную ендіанс цілих чисел для крос-платформних додатків. Вони також іноді стають в нагоді (разом з іншими операторами маніпулювання бітами) під час дрібної двовимірної графіки.


Відряджений, пише перетворювач для набору символів EBCDIC. На жаль, це справді робота на низькому рівні мовою високого рівня, але в деяких випадках це необхідно.
Майкл Медоус

9

Я використовував їх кілька разів, але майже завжди для синтаксичного аналізу бінарного формату файлу.


7

Бітові зрушення швидкі. Вони були реалізовані в наборах команд процесора задовго до того, як були операції поділу та модуля. Багато з нас використовували бітові зсуви для арифметики, прості на олівці та папері, але недоступні на наших центральних процесорах.

Наприклад:

  • Я використовував бітові зрушення для проектів, що передбачають врахування великих композитів до основних факторів.
  • Я також використовував бітові зсуви для пошуку квадратного та кубового коренів довільно великих цілих чисел.

Ви можете опублікувати приклад, як ви використовуєте його для пошуку куба або квадратного кореня? я трохи не бачу, як це можна зробити.
Xsmael

5

Так, все-таки це потрібно.

Наприклад, на моїй роботі ми розробляємо програмне забезпечення для зв'язку з PLC через послідовний порт COMx. Потрібно обробляти біти в байті, ми використовуємо зсув вліво / вправо та логічні оператори OR, XOR та AND щодня.

Наприклад, припустимо, що нам потрібно ввімкнути біт 3 (справа наліво) байта:

Це набагато ефективніше:

Byte B;

B := B XOR 4;

Замість:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

З повагою.


1
Ви можете додати, чому 4 відноситься до біта 3 (справа наліво)
HCP

1
Чому s [5]? Чи не має бути S [2]?
IamIC

1
B: = B XOR 4; У цьому випадку, щоб увімкнути певний біт, чи не слід це просто АБО? Чи не використовується XOR для перемикання? stackoverflow.com/questions/47981/…
Харі

4

Коли я писав мовою асемблера, мій код був повний зміщення бітів і маскування.

Чи зробив це чималу суму і в С.

Не зробив цього багато в JavaScript або на мовах серверів.

Мабуть, найкращим сучасним використанням є проходження через упакований масив булевих значень, представлених як одиниці та нулі. Раніше я завжди залишав зсув і перевіряв наявність бітового знака в збірці, але мовами вищого рівня ви порівнюєте зі значенням.

Наприклад, якщо у вас 8 бітів, ви перевіряєте верхній біт із "if (a> 127) {...}". Потім ви залишили зсув (або помножте на 2), зробіть "і" з 127 (або зробіть віднімання 256, якщо встановлено останній біт), і зробіть це знову.


3

Я багато використовував їх для стиснення / декомпресії зображень, де біти в растровому зображенні стискалися. Використовуючи http://en.wikipedia.org/wiki/Huffman_coding , стискаються речі складаються з різної кількості бітів (не всі вони вирівняні за байтами), і тому вам потрібно їх бітовий зсув під час кодування або декодування. .


3

Наприклад, у криптографічних методах реалізація на таких мовах, як C, C ++. Двійкові файли, алгоритми стиснення та логічні операції зі списками - побітова робота завжди хороша =)


3

Зміщення бітів не вирішує проблем програмування високого рівня, але просто нам іноді доводиться вирішувати проблеми нижчого рівня, і зручно не писати окрему бібліотеку на C, щоб це зробити. Саме тоді він звикає найбільше - це моє припущення.

Я особисто використовував його при написанні кодера для перетворювача наборів символів EBCDIC .


3

Так, у мене є. Як ви можете підозрювати, це, швидше за все, можна знайти в програмуванні низького рівня, наприклад, розробці драйверів пристроїв. Але я працював над проектом C #, де мені довелося розробити веб-сервіс, який отримував дані з медичних пристроїв. Всі двійкові дані, які зберігав пристрій, були закодовані в пакети SOAP, але двійкові дані були стиснуті та закодовані. Отже, щоб розтиснути його, вам доведеться робити багато-багато бітових маніпуляцій. Крім того, вам доведеться зробити багато бітових зсувів, щоб проаналізувати будь-яку корисну інформацію, наприклад, серійний номер пристрою - нижня половина другого байта або щось подібне. Також я бачив, як деякі люди у світі .NET (C #) використовують маскування бітів та атрибут прапора, особисто мені ніколи не спонукали це робити.


3

так. Я повинен писати алгоритми шифрування раніше, і це, безумовно, використовує їх.

Вони також корисні при використанні цілих чисел тощо для відстеження статусів.



3

Я працюю у виробника комп'ютерної периферії. Я стикався і мусив впроваджувати код, який використовує бітові зсуви, майже кожен день.


3

Зміщення бітів багато використовується для розшифровки протоколів онлайн-ігор. Протоколи розроблені для використання якомога меншої пропускної здатності, тому замість передачі кількості гравців на сервері, імен та ін. У int32s вся інформація упакована в якомога менше байт. У наш час це не є необхідним для більшості людей, які використовують широкосмуговий доступ, але коли вони були спочатку розроблені, люди використовували 56 тисяч модемів для ігор, тому кожен біт рахувався.

Найвидатніші приклади цього - у багатокористувацьких іграх Valve, зокрема Counter-Strike, Counter-Strike Source. Протокол Quake3 також такий самий, проте Unreal не такий тонкий.

Ось приклад (.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

Звичайно, чи будете ви розглядати це як реальний проект чи просто хобі (на C #), вирішувати вам.



2

Знайдіть найближчу степінь двох, більших або рівних даному числу:

1 << (int)(ceil(log2(given)))

Необхідний для текстурування на апаратному забезпеченні, яке не підтримує довільні розміри текстур.


1

Так, використовував їх у синтаксичному аналізаторі транспортних потоків MPEG2-2. Це було простіше і легше для читання.


1

Мені довелося написати програму для синтаксичного аналізу файлів .ifo на DVD-дисках. Це ті поля, які пояснюють, скільки заголовків, глав, меню тощо на диску. Вони складаються з упакованих бітів усіх розмірів та вирівнювань. Я підозрюю, що багато бінарних форматів вимагають подібного зміщення бітів.


1

Я бачив побітові оператори, які використовувались, коли в якості параметра властивості використовувались кілька прапорів. Наприклад, число 4 = 1 0 0 означає, що встановлений один із трьох прапорів. Це не добре для загальнодоступного API, але в особливих випадках це може пришвидшити процес, оскільки перевірка на біти є швидкою.


1

Кожен bitblt-er, який я коли-небудь писав, не міг бути виконаний без можливості ковзання бітів вліво та вправо.


1

Я використовував їх в іграх для упаковки купу прапорів в один байт / символ для збереження на картці даних. Такі речі, як зберігання статусу, який можна заблокувати, тощо. Сьогодні це не так вже й багато, але це може заощадити роботу.


1

Я використовую його у проекті для вбудованої системи, яка повинна зчитувати дані EDID монітора. Деякі дані в EDID кодуються таким чином:

Байт # 3:
Горизонтальне затухання - 8 біт внизу
Байт # 4:
Нижнє занурення: Горизонтальне затухання - верхні 4 біта
Верхнє занурення: щось інше

1

Так, при виконанні двійкового зв'язку між програмами Java та C # один є впорядкуванням байтів великого кінця, а інший - мало-ендіанським (не обов’язково в цьому порядку). Я створив клас InputStream, який міг читати числа з іншим порядком байтів, і він використовував зміщення байтів, щоб працювати.

Іноді, коли ви хочете помістити 4 шорти в 4 байти довжини, це може бути випадком використання зсуву байтів. Я думаю, що це зробив багато років тому ...


1

Ще одна дуже поширена справа - робити 4-бітний зсув при витягуванні великого перекусу байта, тобто

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)

Особливо актуально, якщо ви працюєте безпосередньо з апаратним забезпеченням, отримуючи дані безпосередньо з регістрів із довільними відображеннями бітів.
Кріс,

0

Зміщення бітів також потрібно при спілкуванні з еквівалентом "нижчого рівня", еквівалентними цифровими Ethernet-IO-коробками або ПЛК, які зазвичай упаковують окремі вхідні / вихідні значення у байти.


0

Так, зсув бітів використовується постійно у вбудованому програмному забезпеченні низького рівня. Його також можна використовувати як майже магічний трюк для здійснення надзвичайно швидких математичних операцій, подивіться

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/


0

Так, весь час. Як і ці макроси для пакування та розпакування координат 3space до / з 32-бітового цілого числа:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        

0

Одного разу (багато, багато років тому) я написав вихідну програму для проекту, який створював електронні таблиці Excel, використовуючи структуру Excel Oper. Це був двійковий формант файлу, який вимагав великої кількості бітових обертів. Наступне посилання надає смак структури Oper Safari Books .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.