{"id":9218,"date":"2025-01-10T02:00:00","date_gmt":"2025-01-10T07:00:00","guid":{"rendered":"https:\/\/www.both.org\/?p=9218"},"modified":"2025-01-10T09:45:23","modified_gmt":"2025-01-10T14:45:23","slug":"using-bit-fields-and-bit-masks-in-c","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=9218","title":{"rendered":"Using bit fields and bit masks in C"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"9218\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p>The C programming language offers many ways to arrange data in memory. If you need to combine several variables, one way to do it is with a <em>data structure<\/em>, like this for an x,y coordinate system:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>typedef struct {\n  float x;\n  float y;\n} coord_t;<\/code><\/pre>\n\n\n\n<p>This allows you to use the structure like a single variable, comprised of two <code>float<\/code> variables, <code>x<\/code> and <code>y<\/code>. The <code>typedef<\/code> statement associates the <code>struct<\/code> of two float elements to a new variable \u201ctype\u201d called <code>coord_t<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n\ntypedef struct {\n  float x;\n  float y;\n} coord_t;\n\nint main()\n{\n  coord_t pos;\n\n  pos.x = 1.4;\n  pos.y = 3.1;\n\n  printf(\"the x,y coordinate is %f,%f\\n\", pos.x, pos.y);\n\n  return 0;\n}<\/code><\/pre>\n\n\n\n<p>But using a structure like this isn\u2019t always the right approach. Fortunately, C offers another option to combine data using <em>bit fields<\/em> and <em>bit masks<\/em>. To use bit fields, you need to think like a computer and remember that <em>data is stored in bits<\/em>, and each bit is a one or a zero.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bits-and-binary\">Bits and binary<\/h2>\n\n\n\n<p>Let\u2019s say you were writing a chess game in C. One way to track the pieces on the board is by defining a structure that defines each possible piece on the board, and its color, so every square contains an element from that structure. For example, you might have a structure that looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct chess_pc {\n   int piece;\n   int is_black;\n}<\/code><\/pre>\n\n\n\n<p>With this programming structure, your program will know what piece is in every square and its color. You can quickly identify if the piece is a pawn, rook, knight, bishop, queen, or king\u2014and if the piece is black or white. But there\u2019s a more straightforward way to track the same information while using less data and memory. Rather than storing a structure of two <code>int<\/code> values for every square on a chessboard, we can store a single <code>int<\/code> value and use binary bit fields and masks to identify the pieces and color in each square.<\/p>\n\n\n\n<p>To apply bit fields and bit masks to this problem, let\u2019s start by listing the possible chess pieces and assigning a number to each. I\u2019ll help us along to the next step by representing the number in its binary form, the way the computer would track it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>(0 = <code>00000000<\/code>) empty<\/li>\n\n\n\n<li>(1 = <code>00000001<\/code>) pawn<\/li>\n\n\n\n<li>(2 = <code>00000010<\/code>) rook<\/li>\n\n\n\n<li>(3 = <code>00000011<\/code>) knight<\/li>\n\n\n\n<li>(4 = <code>00000100<\/code>) bishop<\/li>\n\n\n\n<li>(5 = <code>00000101<\/code>) queen<\/li>\n\n\n\n<li>(6 = <code>00000110<\/code>) king<\/li>\n<\/ul>\n\n\n\n<p>To list all pieces on a chessboard, we only need the three bits that represent (from right to left) the values 1, 2, and 4. For example, the number 6 is binary <code>110<\/code>. All of the other bits in the binary representation of 6 are zeroes.<\/p>\n\n\n\n<p>And with a bit of cleverness, we can use one of those extra always-zero bits to track if a piece is black or white. We can use the number 8 (binary <code>00001000<\/code>) to indicate if a piece is black. If this bit is 1, it\u2019s black; if it\u2019s 0, it\u2019s white. That\u2019s called a bit field, which we can pull out later using a binary mask.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"storing-data-in-bit-fields\">Storing data in bit fields<\/h2>\n\n\n\n<p>To write a chess program using bit fields and masks, we might start with these definitions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* could also #include &lt;stdint.h> and use uint8_t, which is also 1 byte *\/\ntypedef unsigned char square_t; \/* 1 byte *\/\n\n\/* this uses bits from 0000 (0) to 0110 (6) *\/\n#define EMPTY  0\n#define PAWN   1\n#define ROOK   2\n#define KNIGHT 3\n#define BISHOP 4\n#define QUEEN  5\n#define KING   6\n\n\/* the bit mask for black\/white is 1000 (8) *\/\n#define BLACK  8\n#define WHITE  0\n\n\/* the bit mask for the piece is 0111 (7) *\/\n#define PIECE  7<\/code><\/pre>\n\n\n\n<p>When you assign a value to a square, such as when initializing the chessboard, you can assign a single <code>int<\/code> value to track both the piece and its color. For example, to store a black rook in position 0,0 of an array, you would use this code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int main()\n{\n    square_t board&#91;8]&#91;8]; \/* 0-7 is 8 square, total is 8x8=64 squares *\/\n\n    board&#91;0]&#91;0] = BLACK | ROOK; \/* 1000 | 0010 = 1010 (10) *\/\n...<\/code><\/pre>\n\n\n\n<p>The <code>|<\/code> is a binary <em>Or<\/em>, which means the computer will combine the bits from two numbers. For every bit position, if that bit from either number is 1, the result for that bit position is also 1. Binary <em>Or<\/em> of the value <code>BLACK<\/code> (8, or binary <code>00001000<\/code>) and the value <code>ROOK<\/code> (2, or binary <code>00000010<\/code>) is binary <code>00001010<\/code>, or 10:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   00001000 (8)\nOr 00000010 (2)\n\n   00001010 (10)<\/code><\/pre>\n\n\n\n<p>Similarly, to store a white pawn in position 6,0 of the array, you could use this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int main()\n{\n    square_t board&#91;8]&#91;8]; \/* 0-7 is 8 square, total is 8x8=64 squares *\/\n\n    board&#91;6]&#91;0] = WHITE | PAWN; \/* 0000 | 0001 = 0001 (1) *\/\n...<\/code><\/pre>\n\n\n\n<p>This stores the value 1 because the binary <em>Or<\/em> of <code>WHITE<\/code> (0) and <code>PAWN<\/code> (1) is just 1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   00000000 (0)\nOr 00000001 (1)\n\n   00000000 (1)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"retrieving-bits-with-masks\">Retrieving bits with masks<\/h2>\n\n\n\n<p>During the chess game, the program will need to know what piece is in a square and its color. We can separate the piece using a binary mask.<\/p>\n\n\n\n<p>For example, the program might need to know the contents of a specific square on the board during the chess game, such as the array element at <code>board[5][3]<\/code>. What piece is there, and is it black or white?<\/p>\n\n\n\n<p>The binary <em>And<\/em> operator (<code>&amp;<\/code>) combines two binary values so that for any bit position, if that bit in both numbers is 1, then the result is also 1. For example, if a piece in the <code>board<\/code> array has the value 10, we can use a bit mask to write an <code>is_black<\/code> function to determine if the piece is black or white:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int is_black(square_t sq)\n{\n    return (sq &amp; BLACK); \/* uses the bit mask for black\/white *\/\n}<\/code><\/pre>\n\n\n\n<p>This works because the value <code>BLACK<\/code> is 8, or binary <code>00001000<\/code>. And in the C programming language, any non-zero value is treated as <em>True<\/em>, and zero is always <em>False<\/em>. So <code>is_black(board[6][0])<\/code> will return a <em>True<\/em> value (8) if the piece in array element 6,0 is black and will return a <em>False<\/em> value (0) if it is white.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"putting-it-all-together\">Putting it all together<\/h2>\n\n\n\n<p>Let\u2019s combine everything to define an 8&#215;8 chess board with two pieces on it, a black rook and a white pawn. We can then use the bit fields and bit masks to store and retrieve data:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n\n\/* could also #include &lt;stdint.h&gt; and use uint8_t, which is also 1 byte *\/\ntypedef unsigned char square_t; \/* 1 byte *\/\n\n\/* this uses bits from 0000 (0) to 0110 (6) *\/\n#define EMPTY  0\n#define PAWN   1\n#define ROOK   2\n#define KNIGHT 3\n#define BISHOP 4\n#define QUEEN  5\n#define KING   6\n\n\/* the bit mask for black\/white is 1000 (8) *\/\n#define BLACK  8\n#define WHITE  0\n\n\/* the bit mask for the piece is 0111 (7) *\/\n#define PIECE  7\n\nint is_black(square_t sq)\n{\n    return (sq &amp; BLACK); \/* uses the bit mask for black\/white *\/\n}\n\nint main()\n{\n    square_t board&#91;8]&#91;8]; \/* 0-7 is 8 square, total is 8x8=64 squares *\/\n\n    board&#91;0]&#91;0] = BLACK | ROOK; \/* 1000 | 0010 = 1010 (10) *\/\n    board&#91;6]&#91;0] = WHITE | PAWN; \/* 0000 | 0001 = 0001 (1) *\/\n\n    printf(\"the rook at &#91;0]&#91;0] is %d=%s\\n\", board&#91;0]&#91;0],\n    (is_black(board&#91;0]&#91;0]) ? \"black\" : \"white\") );\n\n    printf(\"the pawn at &#91;6]&#91;0] is %d=%s\\n\", board&#91;6]&#91;0],\n    (is_black(board&#91;6]&#91;0]) ? \"black\" : \"white\") );\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>If we compile and run this program, we\u2019ll see that the rook is black and the pawn is white:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>the rook at &#91;0]&#91;0] is 10=black\nthe pawn at &#91;6]&#91;0] is 1=white<\/code><\/pre>\n\n\n\n<p>Using bit fields and masks is a common method to combine data without using structures. They are worth adding to your programmer\u2019s \u201ctool kit.\u201d While data structures are a valuable tool for ordered programming where you need to track related data, using separate elements to track single <em>True<\/em> or <em>False<\/em> values (such as the colors of chess pieces) is less efficient. In these cases, consider using bit fields and masks to combine your data more efficiently.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using bit fields and bit masks is a common method to combine data without using more complex structures.<\/p>\n","protected":false},"author":33,"featured_media":3514,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[150],"tags":[152],"class_list":["post-9218","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming","tag-programming"],"modified_by":"Jim Hall","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/9218","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/33"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9218"}],"version-history":[{"count":3,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/9218\/revisions"}],"predecessor-version":[{"id":9243,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/9218\/revisions\/9243"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/3514"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}