Notes for Lecture 7 - February 6, 2007 ====================================== * Roundoff errors in floating point computations ** Problem: floating point arithmetic does not obey usual mathematical laws *** Example: (a+b)+c not necessarily same as a+(b+c). Using 2-digit decimal arithmetic, we have 9.9 + 0.3 = 10.2 --> 10. after rounding to 2 digits 10 + 0.4 = 10.4 ==> 10 after rounding so (9.9 + 0.3) + 0.4 = 10. However, 0.3 + 0.4 = 0.7 9.9 + 0.7 = 10.6 --> 11 after rounding so 9.9 + (0.3 + 0.4) = 11. *** The actual order in which the operations are performed is determined by: **** The way the source code breaks up the computation. **** The compiler being used **** The amount of compilier optimization being used. ** Amount of precision is determined by the particular processor architectures ** 80-bit "feature" in Intel i386 architecture *** How it works Intel i386 floating point hardware supports 80 bit floating piont format, with 64 bits of significand (as opposed to the 53 bits in a double). If 80-bit mode is enabled, and if the computation does not requre that intermediate results be stored to memory as a double, then the total amount of roundoff error gets considerably reduced. *** Problems The difficulty is that it is difficult for the programmer to control the precision of computation when it is rather unpredictable when 64 bits of precision are maintained and when those 11 lower-bits will get thrown away. * Logical values ** Old C *** 0 means false *** Non-zero integer means true *** Comparison and logical operations return 1 for true. ** Type bool *** Recent addition to C *** Must #include ,stdbool.h> *** Boolean type is called "bool"; values are true (=1) and false (=0). *** Like type char, bool remains a "numeric" type *** Nonsensical operationss can be performed on operands of type bool. * Expressions ** Parse trees ** Precedence and associativity of operators *** {} [] -> . *** unary operators: - ++ -- ! & * ~ (type) sizeof *** * / % *** + - *** << >> (shift) *** < <= > >= (relational) *** == != (equality) *** & (bitwise and) *** ^ (bitwise exclusive or) *** | (bitwise or) *** && (logical and) *** || (logical or) *** ?: (conditional expression) *** = op= (assignment) *** , (sequencing) ** Evaluation rules *** Most operators (e.g. +) can evaluate its operands in either order *** Logical operators && and || use "shortcircuit" evaluation **** Left operand is evaluated first. **** If result is determined, evaluation of right operand is omitted. Example: (2 == 3) && expr is false no matter what expr would return, so expr is not evaluated. **** Evaluation of opeands isn't necessarily left to right Example: (a && b) || c If a evaluates to false, then b is skipped, but c is evaluated. If a evaluates to true, then b is evaluated, and if it is true then c is skipped, but if it is false, then c is evaluated. ** Mixed mode arithmetic [not covered in lecture] *** More restrictive type is converted to less restrictive type before operation. *** Type of result is that of less restrictive type. *** Examples **** short + long converts first arg to long and does a long operation. **** double + int converts second arg to double and does floating point addition. *** mixtures of signed and unsigned are more complicated since neither may be "less" restrictive ** Division and remainder [discussed previously] ** Type casts [discussed previously] ** Assignment Assignment produces a result which can be used by other operators. ** Shorthand assignment, e.g., += [discussed previously] ** Increment/decrement [discussed previously] ** Postincrement delays [not covered in lecture] *** New value of variable after postincrement (++ operator) not always stored back immediately Example: x=5; y = x++ + x++; could result in y==10 or y==11, depending on whether x was updated immediately or not. It could also end up with x=6 or x=7 for the same reason. * Strings ** A C-string *** Is sequence of non-null characters followed by a null bype (character '\0' == 0). *** Stored in an array of type char []. *** Elements are individual characters Example: type char mystr[8] = "the cat" creates an array of 8 bytes: mystr[0] == 't' mystr[1] == 'h' mystr[2] == 'e' mystr[3] == ' ' mystr[4] == 'c' mystr[5] == 'a' mystr[6] == 't' mystr[7] == '\0' == 0 Array elements can be changed, so after mysr[4] = 'r', the string in the array is "the rat". Can be printed using %s format specifier, e.g. printf( "%s\n", mystr );