/* Bitwise and: & int x = 0xABCD; // …0000 1010 1011 1100 1101 int y = 0xFF; // …0000 0000 0000 1111 1111 int z = x & y; // …0000 0000 0000 1100 1101 == 0xCD Bitwise or: | int x = 0x60; // …0110 0000 int y = 0x2B; // …0011 1011 int z = x | y; // …0111 1011 == 0x7B Left shift: << int z = 0xF << 4; //shift 0xF 4 bits to the left. 0xF0 Arithmetic Right shift: >>. (fill with sign bit) int z = 0xAB >> 4; //shift 0xAB 4 bits right. 0xA. int z2 = 0x81234567 >> 4; //shift a negative number right. //0xF8123456 Logical Right shift: >> (fill with 0) on unsigned ints int z2 = (unsigned int)0x81234567 >> 4; //shift a negative number right. //0x08123456 */ #include <stdio.h> #include <stdlib.h> const int BIN_LENGTH = 32; //using bits for multiple booleans //each flag is represented by a single bit in a different position //this allows us to combine them without changing their values const int IS_VALID = 1; //1 0x1 const int IS_READABLE = 1 << 1; //2 0x2 const int IS_WRITABLE = 1 << 2; //4 0x4 const int IS_SOMETHING_ELSE = 1 << 3; //8 0x8 //global variable int count = 0; char *printBinaryString(char *result, unsigned int value){ unsigned int mask = 1; for(int i = 0; i < BIN_LENGTH; i++){ result[BIN_LENGTH-1-i] = (value & mask)?'1':'0'; mask = mask << 1; } //add null terminal result[BIN_LENGTH] = '\0'; return result; } void printValue(char *label, unsigned int value){ //print label in 20 spaces printf("%d: %s\n", ++count, label); //print the decimal representation of value printf("\tDEC: %d\n", value); //print the Hexadecimal representation of value //Note %08X: pad up to 8 hex digits with 0s // need to print the 0x printf("\tHEX: 0x%08X\n", value); //print the binary representation of value //first create it as a string char bStr[BIN_LENGTH+1]; printf("\tBIN: %s\n\n", printBinaryString(bStr,value)); } int main(void) { //a hex value int hex = 0xDEADBEEF; printValue("32 bit int", hex); //least significant 2 bytes (4 hex digits) //0xFFFF is 16 0's followed by 16 1's //& is the bitwise and, so the result is each binary digit of hex //anded with each binary digit of 0xFFFF printValue("2 least sig. bytes", hex & 0xFFFF); //most significant 4 bytes //shift the value to the right, sign extended (fill in with the most significant bit) //this preserves negative numbers printValue("arith. shift right", hex >> 16); //try logical shift - no sign extensions (fill in with 0's) printValue("logical shift right", (unsigned int)hex >> 16); //The following are the same: // 256 // 2 to the 8th // 1 << 8 // 1 0000 0000 in binary //a note about div and mod, applying them to a negative value will produce // a negative result //using div printValue("AB76 div 256", 0xAB76 / 256); //using mod printValue("AB76 mod 256", 0xAB76 % 256); //we can combine flags with bitwise or (or addition) to remember them in one value. int flags = IS_VALID | IS_WRITABLE; printValue("Flags variable", flags); //we can then check to see if a particular flag is set using bitwise and if((flags & IS_WRITABLE) != 0) { //here is the math: //writable 0100 //flags 0101 // & 0100 printf("WRITABLE flag set.\n"); } else { printf("WRITABLE flag NOT set.\n"); } //Read a number in hex unsigned int in; printf("Enter a number: "); scanf("%x", &in); printValue("Input as hex:", in); return EXIT_SUCCESS; }