cse202: lecture 10athe ohio state university1 numerical error

33
CSE202: Lecture 10A The Ohio State University 1 Numerical Error

Upload: jocelyn-mitchell

Post on 22-Dec-2015

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 1

Numerical Error

Page 2: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 2

Data Types: Floating Point Numbers (1)

• Floating-point numbers have a decimal point, and they can also be signed or unsigned.

• There are three types: float, double, or long double.– The differences between these are their

supported range and precision.

Page 3: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 3

Data Types: Floating Point Numbers (2)

• To represent a floating point number:– float uses 32 bits (4 bytes)– double uses 64 bits (8 bytes)– long double uses 128 bits (16 bytes)

• The tradeoff is storage vs. precision and range

• What exactly is the precision and range, and how are floating point numbers represented in binary format? IEEE 754 Standard

Page 4: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 4

Numerical Error (1)// example of numerical error

#include <iostream>using namespace std;

int main(){ double x(0.7); // initialize x to 0.7

cout << "(0.7-0.6)*10.0 - 1.0 = " << (x-0.6)*10.0 - 1.0 << endl;

return 0;}

Page 5: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 5

> numerical_error1.exe(0.7-0.6)*10.0 - 1.0 = -2.22045e-16

>

double x(0.7); // initialize x to 0.7

cout << "(0.7-0.6)*10.0 - 1.0 = " << (x-0.6)*10.0 - 1.0 << endl;

Page 6: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 6

Numerical Error (2)// print 18 significant digits

#include <iostream>using namespace std;

int main(){ double x(0.7); // initialize x to 0.7

cout << "x = " << x << endl;

cout.precision(18); // output 18 significant digits cout << "x = " << x << endl; return 0;}

Page 7: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 7

> numerical_error2.exex = 0.7x = 0.699999999999999956

>

double x(0.7); // initialize x to 0.7

cout << "x = " << x << endl;

cout.precision(18); // output 18 significant digits

cout << "x = " << x << endl;

Page 8: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 8

Numerical Error

• Computers store floating point numbers in binary (base 2 or as 0’s and 1’s).

• There is no way to represent 0.7 precisely in base 2.

• There is no way to represent 0.1 precisely in base 2!

Page 9: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 9

Numerical Error (3). . .int main(){ cout.precision(18); // output 18 significant digits cout << "0.0 = " << 0.0 << endl; cout << "0.1 = " << 0.1 << endl; cout << "0.2 = " << 0.2 << endl; cout << "0.3 = " << 0.3 << endl; cout << "0.4 = " << 0.1 << endl; cout << "0.5 = " << 0.5 << endl; cout << "0.6 = " << 0.6 << endl; cout << "0.7 = " << 0.7 << endl; cout << "0.8 = " << 0.8 << endl; cout << "0.9 = " << 0.9 << endl; cout << "1.0 = " << 1.0 << endl; return 0;}

Page 10: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 10

> numerical_error3.exe0.0 = 00.1 = 0.1000000000000000060.2 = 0.2000000000000000110.3 = 0.2999999999999999890.4 = 0.1000000000000000060.5 = 0.50.6 = 0.5999999999999999780.7 = 0.6999999999999999560.8 = 0.8000000000000000440.9 = 0.9000000000000000221.0 = 1>

… cout.precision(18); // output 18 significant digits cout << "0.0 = " << 0.0 << endl; cout << "0.1 = " << 0.1 << endl;…

Page 11: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 11

Floating Point Accuracy in Conditional Expressions

Page 12: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 12

Floating Point Accuracy Issue (1)

• WARNING: when comparing floating point numbers (of any kind: float, double, long double, …) you cannot use the == operator reliably

• This is a computer limitation. Two numbers, which should be equal, may not be stored as precisely equal in the computer.

– Remember numerical accuracy: how would 0.1 be represented in binary notation? It is not possible to add negative powers of 2’s to get an exact representation of 0.1

– Instead, we only get a very good approximation but is still NOT exactly equal to 0.1

Page 13: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 13

Floating Point Accuracy Issue (2)

• Check it out:

float x(0.1);double y(0.1);cout << setprecision(20) << x << endl;

cout << setprecision(20) << y << endl;

• You should also notice how the doubly precise representation for y gives a far better approximation of 0.1 than that of x, which is only represented by single precision!

• Regardless of how closely the number is to 0.1, it certainly is not equivalent

Page 14: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 14

Floating Point Accuracy Issue (3)

float x(0.1);

double y(0.1);

if (x == y)

{

cout << “x equals y” << endl;

}

• The above cout statement will never execute because x and y are not equal (they’re VERY close, but not equal), and therefore the if-statement will not succeed!!

Page 15: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 15

Be Consistent

• Always use the same data type for floating point variables.

• In C++, floating point expressions default to double. Consider the expression:cout << 4 * 9.34 << endl;

• The number 9.34 is not stored in a variable, but it still needs to be stored SOMEWHERE in memory. So what type is it? By default, C++ stores is as a double.

• This is why we ONLY use double (and not float or long double) in this course!

Page 16: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 16

Floating Point Accuracy Issue (3)

double x(0.1);

double y(0.1);

if (x == y)

{

cout << “x equals y” << endl;

}

• The above cout statement will execute since x equals y.

Page 17: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 17

accuracyError.cpp// error caused by lack of accuracy#include <iostream>using namespace std;

int main(){ double x(0.1); double y(1e-6); // y = 10^(-6)

if (x == (1e5*y)) // if (x == 10^5*10^(-6)) { cout << x << " equals 1e5 x " << y << endl; } else { cout << x << " does not equal 1e5 x " << y << endl; }

return 0;}

Page 18: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 18

> accuracyError.exe0.1 does not equal 1e5 x 1e-06

>

double x(0.1);

double y(1e-6); // y = 10^(-6)

if (x == (1e5*y)) // if (x == 10^5*10^(-6))

{

cout << x << " equals 1e5 x " << y << endl;

}

else

{

cout << x << " does not equal 1e5 x " << y << endl;

}

Page 19: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 19

Floating Point Accuracy Issue (4)

• Instead of checking:if (operand1 == operand2)

• See if the difference between them is small enough to assume truth:if (abs(operand1 - operand2) < 0.000001)

Page 20: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 20

Floating Point Accuracy Issue (5)

Or, better yet:if (abs(operand1 – operand2) < EPSILON)

1. where EPSILON is some constant you have previously declared, and

2. abs() is the absolute value function for floating point numbers available by including the cmath library

Page 21: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 21

accuracyExample.cpp// approximating numbers near zero

#include <iostream>#include <cmath>using namespace std;

int main(){ double EPSILON(1e-12); double x(0.1); double y(1e-6); // y = 10^(-6)

if (abs(x - (1e5*y)) < EPSILON) // if (abs(x-10^5*10^(-6)) < EPSILON) { cout << x << " equals 1e5 x " << y << endl; } else { cout << x << " does not equal 1e5 x " << y << endl; }

return 0;}

Page 22: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 22

> accuracyExample.exe0.1 equals 1e5 x 1e-06

>

double EPSILON (1e-12);

double x(0.1);

double y(1e-6); // y = 10^(-6)

if (abs(x - (1e5*y)) < EPSILON) // if (abs(x-10^5*10^(-6)) < EPSILON)

{

cout << x << " equals 1e5 x " << y << endl;

}

else

{

cout << x << " does not equal 1e5 x " << y << endl;

}

Page 23: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 23

Type Casting

Page 24: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 24

Type Casting (1)

• Review: We saw one form of coercion through assignment:int a, b;double c;c = a * b;

• a * b is an integer but the result is converted to a double when assigned to c.

• This type of coercion is implicit

Page 25: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 25

Type Casting (2)

• There is another type of coercion, called “type casting”, which allows the programmer to explicitly force a data type onto an expression.

• The cast operator is:

dataType(expression)

Page 26: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 26

Type Casting (3)

• Example:int x = 5;

double y = log(double(x));

• Alternative format (C version):

int x = 5;

double y = log((double)(x));

Page 27: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 27

logError.cpp// example of cmath function log#include <iostream>#include <cmath>

using namespace std;

int main(){ int value(0);

cout << "Enter value: "; cin >> value;

// log(value) generates a compiler error cout << "At 10% interest, it will take " << log(value)/log(1.1) << " years for a $1 investment to be worth $" << value << "." << endl; return 0;}

Page 28: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 28

> g++ logError.cpp –o logError.exeCompiling logError.cpp into logError.exe.logError.cpp: In function `int main()':logError.cpp:16: call of overloaded `log(int&)' is ambiguous/usr/include/iso/math_iso.h:52: candidates are: double log(double)/usr/local/include/g++-v3/bits/std_cmath.h:333: long double std::log(long double)/usr/local/include/g++-v3/bits/std_cmath.h:323: float std::log(float)

…// log(value) generates a compiler error

cout << "At 10% interest, it will take " << log(value)/log(1.1)

<< " years for a $1 investment to be worth $" << value << "." << endl;

Page 29: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 29

logTypeCast.cpp#include <iostream>#include <cmath>using namespace std;

int main(){ int value(0);

cout << "Enter value: "; cin >> value;

// type cast value to double

cout << "At 10% interest, it will take " << log(double(value))/log(1.1) << " years for a $1 investment to be worth $" << value << "." << endl; return 0;}

Page 30: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 30

> logExample.exe

Enter value: 10

At 10% interest, it will take 24.1589 years for a $1 investment to be worth $10.

>

// type cast value to double

cout << "At 10% interest, it will take " << log(double(value))/log(1.1)

<< " years for a $1 investment to be worth $" << value << "." << endl;

Page 31: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 31

lower2Upper.cpp...int main(){ int ascii_A(0), ascii_B(0); char a, b;

cout << "Enter initials (2 char): "; cin >> a >> b ;

cout << "Ascii " << a << ": " << int(a) << endl; cout << "Ascii " << b << ": " << int(b) << endl;

ascii_A = int(a)-32; ascii_B = int(b)-32;

cout << "Initials: "; cout << char(ascii_A) << char(ascii_B) << endl; return 0;}

Page 32: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

ASCII Code

CSE202: Lecture 10A The Ohio State University 32

Code Char

32 Space

33 !

34 "

35 #

36 $

37 %

38 &

39 '

40 (

41 )

… …

Code Char

48 0

49 1

50 2

51 3

52 4

53 5

54 6

55 7

56 8

57 9

… …

Code Char

65 A

66 B

67 C

68 D

69 E

70 F

71 G

72 H

73 I

74 J

… …

Code Char

97 a

98 b

99 c

100 d

101 e

102 f

103 g

104 h

105 i

106 j

… …

Page 33: CSE202: Lecture 10AThe Ohio State University1 Numerical Error

CSE202: Lecture 10A The Ohio State University 33

… cout << "Ascii " << a << ": " << int(a) << endl; cout << "Ascii " << b << ": " << int(b) << endl; ascii_A = int(a)-32; ascii_B = int(b)-32;

cout << "Initials: "; cout << char(ascii_A) << char(ascii_B) << endl;…

> lower2Upper.exe

Enter initials (2 char): dj

Ascii d: 100

Ascii j: 106

Initials: DJ

>