Numerical Error

1 / 33

# Numerical Error - PowerPoint PPT Presentation

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.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about 'Numerical Error' - ash

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

### Numerical Error

The Ohio State University

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

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

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

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

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

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

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

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

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

### Floating Point Accuracy in Conditional Expressions

The Ohio State University

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

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

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

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

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

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

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

Floating Point Accuracy Issue (4)

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

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

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

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

### Type Casting

The Ohio State University

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

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

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

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

// 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

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

// 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

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

ASCII Code

The Ohio State University

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