Bitwise Operators#
Representations#
int a = 33333, b = -77777;
char c = 'Z';
int a = 1 << 31; /* shift 1 to the high bit */
unsigned b = 1 << 31;
# @title
%%writefile shifting.c
#include <stdio.h>
int main() {
// Original values
char c = 'Z'; // Character 'Z'
int a = 1 << 31; // Signed int with highest bit set
unsigned b = 1 << 31; // Unsigned int with highest bit set
// Before shifts
printf("Before shifts:\n");
printf("c = %c (ASCII %d)\n", c, c);
printf("a = %d\n", a);
printf("b = %u\n", b);
// Shift operations
char c_shifted = c << 4;
int a_shifted = a >> 3;
unsigned b_shifted = b >> 3;
// After shifts
printf("\nAfter shifts:\n");
printf("c<<4 = %c (ASCII %d)\n", c_shifted, c_shifted);
printf("a>>3 = %d\n", a_shifted);
printf("b>>3 = %u\n", b_shifted);
return 0;
}
Cell In[1], line 5
int main() {
^
SyntaxError: invalid syntax
# @title
!gcc shifting.c -o shifting
!./shifting
Bit Print an int Expression#
#include <limits.h>
void bit_print(int a)
{
int i = 0;
int n = sizeof(int) * CHAR_BIT; /*in limits.h*/
int mask = 1 << (n - 1); /*mask = 100...0*/
for (i = 1; i <= n; ++i)
{
putchar(((a & mask) == 0) ? '0' : '1');
a <<= 1;
if (i % CHAR_BIT == 0 && i < n)
putchar(' ');
}
}
Pack 4 chars into an int#
#include <limits.h>
int pack( char a, char b, char c, char d )
{
int p = a; /*p will be packed with a, b, c, d*/
p = (p << CHAR_BIT) | b;
p = (p << CHAR_BIT) | c;
p = (p << CHAR_BIT) | d;
return p;
}
Unpack a byte from an int#
#include <limits.h>
char unpack( int p, int k ) /*k = 0, 1, 2 or 3*/
{
int n = k * CHAR_BIT; /*n = 0, 8, 16 or 24*/
unsigned mask = 255; /*low order byte*/
mask <<= n;
return ( ( p & mask ) >> n );
}
Bitwise used case 1#
#include <stdio.h>
// Define logging options
#define LOG_TIME 0x01 // 0b00000001
#define LOG_DATE 0x02 // 0b00000010
#define LOG_USER 0x04 // 0b00000100
#define LOG_COUNT 0x08 // 0b00001000
#define LOG_ALL 0xFF // 0b11111111
#define LOG_FULL 0xFF // 0b11111111
void log_event(int log_options) {
if (log_options & LOG_TIME) {
printf("Logging time...\n");
}
if (log_options & LOG_DATE) {
printf("Logging date...\n");
}
if (log_options & LOG_USER) {
printf("Logging user...\n");
}
if (log_options & LOG_COUNT) {
printf("Logging count...\n");
}
}
int main() {
int log_settings = LOG_TIME | LOG_USER; // Enable only time and user logging
printf("Custom log settings:\n");
log_event(log_settings);
printf("\nFull log settings:\n");
log_event(LOG_ALL); // Enable all logging options
return 0;
}
Bitwise used case 2#
#include <stdio.h>
#include <stdint.h>
uint64_t array_of_bits = 0; // A 64-bit field initialized to 0
#define SET_BIT(BF, N) (BF |= ((uint64_t)0x1 << N)) // Set the N-th bit
#define CLR_BIT(BF, N) (BF &= ~((uint64_t)0x1 << N)) // Clear the N-th bit
Bitwise used case 3 (RGB565)#
#include <stdio.h>
int main() {
unsigned char r = 5, g = 12, b = 25; // Red, Green, Blue (values 0-31)
unsigned short packed_color = 0; //16 bit
// Pack the 5-bit RGB values into a single 16-bit integer
packed_color = (r << 11) | (g << 5) | b;
printf("Packed color: 0x%04X\n", packed_color);
// Unpack the RGB values
unsigned char unpacked_r = (packed_color >> 11) & 0x1F;
unsigned char unpacked_g = (packed_color >> 5) & 0x1F;
unsigned char unpacked_b = packed_color & 0x1F;
printf("Unpacked - R: %u, G: %u, B: %u\n", unpacked_r, unpacked_g, unpacked_b);
return 0;
}
Summary – C part#
Lexical elements (Ch. 2)
Fundamental data types (Ch. 3)
Flow of control (Ch. 4)
Functions (Ch. 5); Runtime environment
Arrays, pointers and strings (Ch. 6); Dynamic * matrix allocation (Ch. 12.6)
Preprocessor (Ch. 8)
Structures (Ch. 9)
Linked lists (Ch. 10)
Input/output and files (Ch. 11)