1 / 33

Numerical Error

Numerical Error. 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.

ash
Télécharger la présentation

Numerical Error

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Numerical Error 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 longdouble. • The differences between these are their supported range and precision. 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 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; } The Ohio State University

  5. 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; … > numerical_error1.exe (0.7-0.6)*10.0 - 1.0 = -2.22045e-16 > 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; } The Ohio State University

  7. double x(0.7); // initialize x to 0.7 cout << "x = " << x << endl; cout.precision(18); // output 18 significant digits cout << "x = " << x << endl; … > numerical_error2.exe x = 0.7 x = 0.699999999999999956 > 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! 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; } The Ohio State University

  10. cout.precision(18); // output 18 significant digits cout << "0.0 = " << 0.0 << endl; cout << "0.1 = " << 0.1 << endl; … > numerical_error3.exe 0.0 = 0 0.1 = 0.100000000000000006 0.2 = 0.200000000000000011 0.3 = 0.299999999999999989 0.4 = 0.100000000000000006 0.5 = 0.5 0.6 = 0.599999999999999978 0.7 = 0.699999999999999956 0.8 = 0.800000000000000044 0.9 = 0.900000000000000022 1.0 = 1 > The Ohio State University

  11. Floating Point Accuracy in Conditional Expressions 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 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 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!! 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! 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. 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; } The Ohio State University

  18. 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; } … >accuracyError.exe 0.1 does not equal 1e5 x 1e-06 > 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) The Ohio State University

  20. Floating Point Accuracy Issue (5) Or, better yet: if (abs(operand1 – operand2) < EPSILON) • where EPSILON is some constant you have previously declared, and • abs() is the absolute value function for floating point numbers available by including the cmath library 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; } The Ohio State University

  22. 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; } >accuracyExample.exe 0.1 equals 1e5 x 1e-06 > The Ohio State University

  23. Type Casting 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 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) 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)); 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; } The Ohio State University

  28. // 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; … > g++ logError.cpp –o logError.exe Compiling 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) 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; } The Ohio State University

  30. // 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; … > logExample.exe Enter value: 10 At 10% interest, it will take 24.1589 years for a $1 investment to be worth $10. > 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; } The Ohio State University

  32. ASCII Code 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 > The Ohio State University

More Related