400 likes | 514 Views
Bitwise operators. Representing integers. We typically think in terms of decimal (base 10) numbers. Why? A decimal (or base 10) number consists of a sequence of decimal digits (0,1,…,9). 1920 10 = 1x10 3 + 9x10 2 + 2x10 1 + 0x10 0. Least si gnificant digit. Most si gnificant digit.
E N D
Representing integers • We typically think in terms of decimal (base 10) numbers. • Why? • A decimal (or base 10) number consists of a sequence of decimal digits (0,1,…,9). • 192010 = 1x103 + 9x102 + 2x101 + 0x100 Least significant digit Most significant digit
Representing integers • All numbers within the computer are stored as binary numbers. • Why? • A binary (or base 2) number consists of a sequence of bits (0,1). • 1100112 =1x25+1x24+0x23+0x22+1x21+1x20 • Where does the word “bit” come from? Least significant bit Most significant bit
Representing integers • Typical integer sizes: • unsigned char = 8 bits • unsigned short = 16 bits • unsigned int = 32 bits • 1100112 • is 001100112 when stored in an unsigned char • is 00000000001100112 when stored in an unsigned short • is 000000000000000000000000001100112 when stored in an unsigned int • We know that 192010 is the same as 0192010 or 00000000192010.
Boolean (logical) operators • && is and • || is or • ! is not
Boolean (logical) operators • && is and • F && F is F • F && T is F • T && F is F • T && T is T
Boolean (logical) operators • || is or • F || F is F • F || T is T • T || F is T • T || T is T
Boolean (logical) operators • ! is not • !F is T • !T is F
Boolean (logical) operators • ^ is xor • F ^ F is F • F ^ T is T • T ^ F is T • T ^ T is F
Bitwise operators (on integers) • & is bitwise and • | is bitwise or • ~ is bitwise not (1’s complement) • ^ is bitwise xor (exclusive or) • Let’s substitute 1 for T and 0 for F.
Bitwise operators (on integers) • & is bitwise and 110011 (really 00110011 in an 8-bit byte) & 001111 (really 00001111) ------------ 000011 (really 00000011)
Bitwise operators (on integers) • | is bitwise or 110011 (really 00110011 in an 8-bit byte) | 001111 (really 00001111) ------------ 111111 (really 00111111)
Bitwise operators (on integers) • ~ is bitwise not (1’s complement) If x=110011 (really 00110011 in an 8-bit byte) then ~x is 11001100.
Bitwise operators (on integers) • ^ is bitwise xor 110011 (really 00110011 in an 8-bit byte) ^ 001111 (really 00001111) ------------ 111100 (really 00111100)
Other bitwise operators • << is shift bits to the left. • 1 shift to the left is the same as multiplying by 2. • Examples • 10 << 1 is 20 • 7 << 1 is 14 • 7 << 3 is 56 (same as multiplying by 23)
Other bitwise operators • >> is shift bits to the right. • 1 shift to the right is the same as integer division by 2. • Examples • 10 >> 1 is 5 • 27 >> 3 is 3
More examples • unsigned int ui=0; • ui = 10 & 7; • ui = 10 | 7; • ui = 10 ^ 7 • unsigned char uc = ~12;
Bits as binary flags. • An int is 32 bits so we can number each student in the class from 0..31. If the bit for a particular student is 1, then that indicates that they took a quiz. • First, let’s define the students. • #define S0 (1<<0) • #define S1 (1<<1) • #define S2 (1<<2) • #define S3 (1<<3) • #define S4 (1<<4) • . • . • . • #define S31 (1<<31)
Bits as binary flags. • Now let’s define a quiz. • unsigned int quiz1 = 0; • How can we indicate that students 0, 5, and 9 took quiz 1?
Bits as binary flags. • Now let’s define a quiz. • unsigned int quiz1 = 0; • How can we indicate that students 0, 5, and 9 took quiz 1? • quiz1 = (s0 | s5 | s9);
Bits as binary flags. • Now here comes student 12. He takes the quiz on a subsequent day because he was ill. • How do we update quiz1 to indicate that student 12 also took the quiz?
Bits as binary flags. • Now here comes student 12. He takes the quiz on a subsequent day because he was ill. • How do we update quiz1 to indicate that student 12 also took the quiz? • quiz1 |= s12;
Bits as binary flags. • I’d like to write a message that indicates whether or not student 25 took the exam? • How can I do that?
Bits as binary flags. • I’d like to write a message that indicates whether or not student 25 took the exam? • How can I do that? if ((quiz1&s25)!=0) puts(“taken”); else puts(“skipped”); if ((quiz1&s25)==s25) puts(“taken”); else puts(“skipped”); if (quiz1&s25) puts(“taken”); else puts(“skipped”);
Bits as binary flags. • Did both students 22 and 25 take the exam?
Bits as binary flags. • Did both students 22 and 25 take the exam? if ((quiz1&(s22|s25)) == (s22|s25) ) puts(“taken”); else puts(“skipped”); if ((quiz1&s22)!=0 && (quiz1&s25)!=0) …
Bits as binary flags. • Did everyone except for student 25 take the exam?
Bits as binary flags. • Did everyone except for student 25 take the exam? if ( (quiz1&(~s25)) == (~s25) ) puts(“yes”); else puts(“no”);
Bits as binary flags. • I thought student 25 took the exam but I was mistaken. How can I rectify my mistake?
Bits as binary flags. • I thought student 25 took the exam but I was mistaken. How can I rectify my mistake? • quiz1 = quiz1 & (~s25); • quiz1 &= ~s25;
Bits as binary flags. • Finally, I’d like to print out a list of all of the students that took exam 1.
Bits as binary flags. • Finally, I’d like to print out a list of all of the students that took exam 1. int which = 1; for (int i=0; i<32; i++) { ? which <<= 1; }
Bits as binary flags. • I’d like to print out a list of all of the students that took exam 1. int which = 1; for (int i=0; i<32; i++) { if (quiz1&which) printf( “student %d took the quiz. \n”, i ); which <<= 1; }
Bits as binary flags. • Say I also have quiz1 and quiz2. I’d like a list of all of the students that took quiz1 or quiz2 but not both.
Bits as binary flags. • Say I also have quiz1 and quiz2. I’d like a list of all of the students that took either quiz1 or quiz2 but not both. int which = 1; for (int i=0; i<32; i++) { if ( (quiz1&which) ^ (quiz2&which) ) printf( “student %d took either but not both. \n”, i ); which <<= 1; }