Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Detecting the Properties and Limits of Numeric Datatypes -2 : Page 2




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Floating Point Blues
C++ floating point datatypes have finite precision. Hardware-specific vagaries contribute their own share to the truncation and rounding of floating point datatypes. Now you understand why the result of the expression 2.0/3.0 is approximated as 0.66666666666666663 on my machine. This "digital noise" is a fertile source of many bugs. Consider:

double d1=2., d2=3.; d1/=d2; // 2/3 if (d1*10==(20./d2)) //condition should be true, alas { //unreachable code do_equal(); }

The code between the pair of braces is never executed because the subexpressions on both sides of the == operator yield slightly different results: d1*10 is 6.6666666666666661 whereas 20./d2 is 6.6666666666666670. The difference between these two numbers is an artifact of the truncation and approximation incurred by floating point arithmetic. As a workaround, you can replace floating point datatypes with scaled integers. Sometimes however, this isn't an option. Consider a spreadsheet that evaluates complex formulas—it must use floating point types. For such cases, the epsilon constant comes in handy. Epsilon is the difference between 1 and the smallest value greater than 1 that is representable for a given datatype. For example, the epsilon value for type double is:

#include <iostream> #include <limits> using namespace std; cout << numeric_limits<double>::epsilon( ) << endl; //output: 2.22045e-016

To neutralize the effect of digital noise in the if-statement, replace the == operator with an expression that checks whether the two values are roughly identical:

if ( ((d1*10)-(20.0/d2)) <= numeric_limits<double>::epsilon()) { do_equal(); }

If the result of the expression (d1*10)-(20.0/d2) isn't higher than the epsilon for type double, it's practically zero. Hence, the two subexpressions have identical values. Using this technique you can fine-tune the error threshold. For example, if a difference of one billionth or less is insignificant in your application, try the following:

const double BILLIONTH=1./1000000000; if ( ((d1*10)-(20.0/d2)) <= BILLIONTH)

Remember though that epsilon is always the lowest deviation threshold.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date