Бітове поле
Бітове поле (англ. bit field) — це структура даних, що відображається на один або кілька суміжних бітів, виділених для певних цілей, так що будь-який окремий біт або група бітів у межах цієї структури можуть бути встановлені або перевірені.[1][2] Бітове поле найчастіше використовується для подання цілочислових типів із відомою фіксованою бітовою шириною таких як логічні значення.
Бітові поля відрізняються від бітових масив тим, що в них біти не індексуються цілими числами, і бітові поля цілком поміщаються в машинне слово.
Прикладом бітового поля є регістр стану процесора.
Приклади
C
Бітові поля можна використовувати в структурах мови C та C++.
#include <stdint.h>
// opaque and show
enum Visibility : uint8_t {
NO = 0,
YES = 1
};
// line styles
enum LineStyle : uint8_t {
SOLID = 1,
DOTTED = 2,
DASHED = 3
};
// Colors
enum Color : uint8_t {
BLACK = 0,
RED = 0b001,
GREEN = 0b010,
BLUE = 0b100,
YELLOW = RED | GREEN, // 011
MAGENTA = RED | BLUE, // 101
CYAN = GREEN | BLUE, // 110
WHITE = RED | GREEN | BLUE // 111
};
const char* colors[8] = {"Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"};
// bit field box properties
struct BoxProps {
uint32_t opaque : 1;
uint32_t fill_color : 3;
[[maybe_unused]]
uint32_t filler_a : 4; // fill to 8 bits
uint32_t show_border : 1;
uint32_t border_color : 3;
uint32_t border_style : 2;
[[maybe_unused]]
uint8_t filler_b : 0; // fill to nearest byte (16 bits)
uint8_t width : 4; // Split a byte into 2 fields of 4 bits
uint8_t height : 4;
};
int main() {
BoxProps my_box = {
.opaque = YES,
.fill_color = RED,
.show_border = YES,
.border_color = BLUE,
.border_style = SOLID,
.width = 5,
.height = 10
};
}
Розмішення бітових полів у C struct є залежним від реалізації. Для певного розміщення біт для всіх компіляторів, можна емулювати бітові полі бітовими операціями:
#include <stdint.h>
/**
* Each of these preprocessor directives defines a single bit,
* corresponding to one button on the controller.
* Button order matches that of the Nintendo Entertainment System.
*/
enum Key : uint8_t {
KEY_RIGHT = 0b00000001,
KEY_LEFT = 0b00000010,
KEY_DOWN = 0b00000100,
KEY_UP = 0b00001000,
KEY_START = 0b00010000,
KEY_SELECT = 0b00100000,
KEY_B = 0b01000000,
KEY_A = 0b10000000
};
// global state
uint8_t gameControllerStatus = 0;
// Sets the gameControllerStatus using OR
void onKeyPressed(uint8_t key) {
gameControllerStatus |= key;
}
// Clears the gameControllerStatus using AND and ~ (binary NOT)
void onKeyReleased(uint8_t key) {
gameControllerStatus &= ~key;
}
// Tests whether a bit is set using AND
uint8_t isPressed(uint8_t key) {
return gameControllerStatus & key;
}
Rust
Rust не має бітових полів, але для подібних операцій можна використати бітові маски.
impl BoxProps {
// Byte 0
const OPAQUE: u8 = 0b0000_0001;
const FILL_COLOR_MASK: u8 = 0b0000_1110;
// Byte 1
const SHOW_BORDER: u8 = 0b0000_0001;
const BORDER_COLOR_MASK: u8 = 0b0000_1110;
const BORDER_STYLE_MASK: u8 = 0b0011_0000;
// Byte 2
const WIDTH_MASK: u8 = 0b0000_1111;
const HEIGHT_MASK: u8 = 0b1111_0000;
}
impl BoxProps {
fn opaque(&self) -> bool {
self.raw[0] & Self::OPAQUE != 0
}
fn set_opaque(&mut self, v: bool) {
self.raw[0] = (self.raw[0] & !Self::OPAQUE) | (v as u8);
}
fn fill_color(&self) -> u8 {
(self.raw[0] & Self::FILL_COLOR_MASK) >> 1
}
fn set_fill_color(&mut self, v: u8) {
self.raw[0] =
(self.raw[0] & !Self::FILL_COLOR_MASK) | ((v & 0b111) << 1);
}
fn width(&self) -> u8 {
self.raw[2] & Self::WIDTH_MASK
}
fn height(&self) -> u8 {
(self.raw[2] & Self::HEIGHT_MASK) >> 4
}
}
Див. також
- Двійковий код
- Бітова мапа
- Прапорець (програмування)
- Маскування (програмування)
- Program status word
- Регістр стану
- Регістр EFLAGS
- Контрольні регістри
Примітки
- ↑ Penn Brumm; Don Brumm (Серпень 1988). 80386 Assembly Language: A Complete Tutorial and Subroutine Library. McGraw-Hill School Education Group. с. 606. ISBN 978-0-8306-9047-3.
- ↑ Steve Oualline (1997). Practical C Programming. O'Reilly Media, Inc. с. 403–. ISBN 978-1-56592-306-5.
Посилання
- Explanation from a book
- Description from another wiki
- Use case in a C++ guide
- C++ libbit bit library (alternative URL)
- Bit Twiddling Hacks: Several snippets of C code manipulating bit fields
Джерело: стаття у Вікіпедії та історія редагувань (автори).