ARITHMETIC OPERATIONS
WE HAVE THE DATA, WHAT NOW? Operations in C Bit-wise boolean operations ▸ Logical operation ▸ Arithmetic operations ▸ 2
BOOLEAN ALGEBRA Algebraic representation of logic Encode “True” as 1 and “False” as 0 ▸ Operators & | ~ ^ ▸ AND ( & ) OR ( | ) TRUE when both A = 1 AND B = 1 TRUE when either A = 1 OR B = 1 & 0 1 | 0 1 0 0 0 0 0 1 1 0 1 1 1 1 3
BOOLEAN ALGEBRA Algebraic representation of logic Encode “True” as 1 and “False” as 0 ▸ Operators & | ~ ^ ▸ XOR “Exclusive OR” ( ^ ) NOT ( ~ ) TRUE when A or B = “1”, Inverts the truth value but not both. ~ ^ 0 1 0 1 0 0 1 1 0 1 1 0 4
BOOLEAN ALGEBRA Applies to any “Integer” data type That is… long, int, short, char ▸ View arguments as bit vectors ▸ Operations applied in a “bit-wise” manner ▸ Examples: 01101001 01101001 01101001 & 01010101 | 01010101 ^ 01010101 ~ 01010101 01000001 01111101 00111100 10101010 5
PARTNER ACTIVITY 0x69 & 0x55 0x69 ^ 0x55 01101001 01101001 & 01010101 ^ 01010101 01000001 00111100 = 0x41 = 0x3C 0x69 | 0x55 ~ 0x55 01101001 | 01010101 ~ 01010101 01111101 10101010 = 0x7D = 0xAA 6
SHIFT OPERATIONS Left Shift: x << y Argument x 011 00010 Shift bit-vector x left y positions ▸ Throw away extra bits on left ▹ x << 3 00010000 Fill with 0’s on right ▹ Right Shift: x >> y Argument x 101000 10 Shift bit-vector x right y positions ▸ Throw away extra bits on right ▹ Logical >> 2 00101000 Logical shift ▸ Arith. >> 2 11101000 Fill with 0’s on left ▹ Arithmetic shift ▸ Replicate most significant bit on left ▹ Recall two’s complement integer representation ▹ Perform division by 2 via shift ▹ 7
PARTNER ACTIVITY x >> 2 x >> 2 x x << 3 (Logical) (Arithmetic) 0xF0 0x80 0x3C 0xFC 0x0F 0x78 0x03 0x03 0xCC 0x60 0x33 0xF3 0x55 0xA8 0x15 0x15 8
LOGIC OPERATIONS IN C Operations always return 0 or 1 Comparison operators > >= < <= == != ▸ Logical Operators && || ! ▸ Logical AND, Logical OR, Logical negation ▸ In C (and most languages) ▸ 0 is “False” ▹ Anything non-zero is “True” ▹ 9
LOGIC OPERATIONS IN C Examples (char data type) !0x41 == 0x00 ▸ !0x00 == 0x01 ▸ !!0x41 == 0x01 ▸ Watch out! What are the values of 0x69 || 0x55 ▸ 0x69 | 0x55 ▸ Logical operators versus bitwise ▸ boolean operators ▸ What does this expression do? && versus & ▸ (p && *p) ▸ || versus | ▸ == versus = ▸ 10
USING BITWISE AND LOGICAL OPERATIONS Two integers x and y For any processor, independent of the size of an integer, write C expressions without any “=“ signs that are true if: x and y have any non-zero bits in common in their low order byte ▸ 0xFF & (x & y) ▸ x has any 1 bits at higher positions than the low order 8 bits ▸ ~0xFF & x ▸ (x & 0xFF) ^ x ▸ (x >> 8) ▸ x is zero ▸ !x ▸ x == y ▸ !(x ^ y) ▸ 11
ARITHMETIC OPERATIONS Signed / Unsigned Addition and subtraction ▸ Multiplication ▸ Division ▸ 12
UNSIGNED ADDITION WALKTHROUGH Binary (and hexadecimal) addition similar to decimal Assuming arbitrary number of bits, use binary addition to calculate 7 + 7 0111 + 0111 ------ Assuming arbitrary number of bits, use hexadecimal addition to calculate 168+123 (A8+7B) A8 + 7B ---- 13
UNSIGNED SUBTRACTION WALKTHROUGH Binary subtraction similar to decimal Assuming 4 bits, use subtraction to calculate 6 - 3 0110 - 0011 ------ In hardware, done via 2s complement negation followed by addition, (2s complement negation of 3 = ~3 + 1) 0011 => 1100 => 1101 (-3) 0110 + 1101 ------ 14
UNSIGNED SUBTRACTION WALKTHROUGH Hexadecimal subtraction similar to decimal Use subtraction to calculate 266-59 (0x10A – 0x3B) 10A - 03B ----- 15
UNSIGNED ADDITION AND OVERFLOW Suppose we have a computer with 4-bit words What is 9 + 9? 1001 + 1001 = 0010 (2 or 18 % 2 4 ) ▸ With w bits, unsigned addition is regular addition, modulo 2 w Bits beyond w are discarded ▸ 16
PARTNER ACTIVITY Assuming an arbitrary number of bits, calculate 0x693A + 0xA359 -------- What would the result be if a 16-bit representation was used instead? 17
UNSIGNED ADDITION With 32-bits, unsigned addition is modulo 2 32 What is the value of #include <stdio.h> 0xc0000000 unsigned int sum( unsigned int a, unsigned int b) + 0x70004444 { ------------ return a+b; } int main () { unsigned int i=0xc0000000; unsigned int j=0x70004444; printf( "%x\n" ,sum(i,j)); return 0; } Output: 30004444 18
PARTNER ACTIVITY Assuming 5 bit 2s complement representation, what is the decimal value of the following sums: (7 + 11), (-14 + 5), and (-11 + -2) Recall: -16 8 4 2 1 00111 10010 10101 + 01101 + 00101 + 11110 ------- ------- ------- What would the result be if a 16-bit representation was used instead? 19
POINTER ARITHMETIC Always unsigned Based on size of the type being pointed to Incrementing a (int *) adds 4 to pointer ▸ Incrementing a (char *) adds 1 to pointer ▸ 20
PARTNER ACTIVITY Consider the following declaration on char* cp = 0x100; ▸ int* ip = 0x200; ▸ float* fp = 0x300; ▸ double* dp = 0x400; ▸ int i = 0x500; ▸ What are the hexadecimal values of each after execution of these commands? cp++; 0x101 ip++; 0x204 fp++; 0x304 dp++; 0x408 i++; 0x501 21
DATA SIZES IN C C Data Type Typical 32-bit x86-64 char 1 1 short 2 2 int 4 4 long 4 8 float 4 4 double 8 8 pointer 4 8 22
TWO’S COMPLEMENT MULTIPLICATION Same problem as unsigned The bit-level representation for two’s-complement and unsigned is identical This simplifies the integer multiplier ▸ As before, the interpretation of this value is based on signed vs. unsigned Maintaining exact results Need to keep expanding word size with each product computed ▸ Must be done in software, if needed ▸ e.g., by “arbitrary precision” arithmetic packages ▹ 23
MULTIPLICATION BY SHIFTING What happens if you shift a decimal number left one place? 30 10 => 300 10 ▸ Multiplies number by base (10) ▹ What happens if you shift a binary number left one place? 00011 2 => 00110 2 ▸ Multiplies number by base (2) ▹ 24
MULTIPLICATION BY SHIFTING What if you shift a decimal number left N positions? (N = 3) 31 10 => 31000 10 ▸ Multiplies number by (base) N or 10 N (1000 for N = 3) ▸ What if you shift a binary number left N positions? 00001000 2 << 2 = 00100000 2 ▸ (8 10 ) << 2 = (32 10 ) ▸ Multiplies number by (base) N or 2 N ▸ 25
MULTIPLICATION BY SHIFTS AND ADDS CPUs shift and add faster than multiply u << 3 == u * 8 Compiler may automatically generate code to implement multiplication via ▸ shifts and adds Dependent upon multiplication factor ▹ Examples ▸ K = 24 ▹ (u << 5) – (u << 3) == u * 32 – u * 8 == u * 24 K = 18 ▹ (u << 4) + (u << 1) == u * 16 + u * 2 == u * 18 26
DIVISION BY SHIFTING What happens if you shift a decimal number right one digit? 31 10 => 3 10 Divides number by base (10), rounds down towards 0 What happens if you shift an unsigned binary number right one bit? 00000111 2 => 00000011 2 (7 >> 1 = 3) Divides number by base (2), rounds down towards 0 27
DIVISION BY SHIFTING Question: 7 >> 1 == 3 What would you expect the following to give you? -7 >> 1 == ? Try using a byte 7 == 00000111 -7 == 11111001 (flip bits, add 1) -7 >> 1 == 11111100 (-4)! What happens if you shift a negative signed binary number right one bit? Divides number by base (2), rounds away from 0! ▸ 28
WHY ROUNDING MATTERS German parliament (1992) 5% law before vote allowed to count for a party ▸ Rounding of 4.97% to 5% allows Green party vote to count ▸ “Rounding error changes Parliament makeup” Debora Weber-Wulff, The ▸ Risks Digest, Volume 13, Issue 37, 1992 Vancouver stock exchange (1982) Index initialized to 1000, falls to 520 in 22 months ▸ Updates to index value truncated result instead of rounding ▸ Value should have been 1098 ▸ 29
OPERATOR PRECEDENCE What is the output of this code? #include <stdio.h> int main () { int i = 3; printf("%d\n", i*8 - i*2); printf("%d\n", i<<3 – i<<1); } $./a.out 18 6 30
C OPERATOR PRECEDENCE 31
Recommend
More recommend