C++ Precision and Accuracy in floating point
In C++ precision and accuracy are problems which arises when using floating point value.Although C++ provide some standard functions to handle the error which they may introduce in our program, however, it can only handle it to some extent. For instance, when the digits get very large the functions fail to provide the exact value. Nevertheless, in this post we will see what does precision and accuracy mean and also find some ways to handle them correctly; we may require the help of an external library.
A short definition of each of them is given below.
Precision: It is the total number of digits in any number.For example 2.45 has 3 precision value, 0.3 has one precision.
Accuracy: It refers to the degree of exactness or correctness of a number.
Link :Floating point type
Precision
In C++ any floating point type can represent a value up to 6 digits precision, after that the value gets rounded off.Consider the program below.
#include <iostream> using namespace std ; int main( ) { float f=3.455311213 ; double d=3.34545724363 ; long double ld=123.3254235 ; cout<< f << endl << d << endl << ld ; cin.get( ) ; return 0 ; }
The output is,
3.34546
123.325
After the 6th digit the value gets rounded off.
In case of ‘d’ variable, since the 7th digit is greater than 5 the 6th digit value is increased by 1. If the 7th digit is lesser than 5 the 6th digit will remain as it is.
The normal Mathematics rule of rounding off the digit is helpful to some extent in mathematical evaluation but in programming, it can give rise to some unexpected result. Consider the program given below.
#include <iostream> using namespace std ; int main( ) { float f=56.7837 ; f=f*f ; if( f==3224.38858569 ) { cout<<“f is ” << f ; } else cout<< “Something is wrong \n” ; cin.get( ); return 0; }
The output is,
We expect the output to be “f is 3224.39” but it is not, why?
Although (f*f)56.7837 * 56.7837 is 3224.38858569 the value is rounded off, so ‘f’ value is stored as 3224.39 which is not same as 3224.38858569 and hence the unexpected output.
In the above program, the number ‘3224.38858569’ is used directly to compare with the ‘f’ variable, in such case, the number should be casted(‘cast’ means changing the type) to the same type as the variable with which the comparison is made. In this case, cast the number 3224.38858569 to the float type and you will get the expected result. Look at the code below.
Link:C++ casting type
if( f== float(3224.38858569) ) { cout << "f is " << f ; } else cout<< "Something is wrong ";
Now the output is,
By casting the number 3224.38858569 to the float type it got rounded off and the resultant value is same as ‘f’ and the output is what we expected. But in scientific calculation, we cannot always round off the value because we might want a precise measurement of the experiment. For such implementation, C++ provides us with some functions through which we can set the precision to as many digits as we want.
There are two standard functions through which we can set the precision to as many digits as we desire.
i)setprecision( x ): This function is included in <iomanip> header’s file. The parameter ‘x’ is an int type and represent the precision.
ii)ios_base::precision( x ): This function is included under the <iostream> header’s file.
The program below uses the two functions to set the precision value up to 13 digits.
/**the 3rd example ***/ #include <iostream> #include <iomanip> using namespace std ; int main( ) { float f=9.36748573593632392334 ; cout<<“Before setting the precision \n”; cout<< f << endl ; cout<< “After setting the precision up to 13 digits \n” ; cout << setprecision(13) << f << endl ; cout.precision(13) ; cout<< f << endl ; cin.get( ) ; return 0 ; }
The output is,
9.36749
After setting the precision up to 13 digits,
9.367486000061
9.367486000061
The two functions does give us numbers having up to 13 digits precision value, but it is far from equal with the original value, that means it is not accurate. The next section shows how to solve the accuracy problem in C++.
Accuracy
By accuracy we mean how close is the value to the correct value and from the 3rd example(above) we have seen that being precise does not mean the value is always accurate.
Why is accuracy important. Take an example in banking application when Compound interest is calculated, inaccuracy can lead to an incorrect transaction of money. Since C++ does not provide us with any standard library to make a number precise and accurate at the same time, the solution is you can either develop a library of your own that can give a precise and accurate value or you can use a third party library like Boost to get a very precise and accurate value. The program given below shows how to obtain a precise and accurate value using Boost library.
/*** Obtaining precise and accurate value using Boost library***/ #include <iostream> #include <iomanip> #include <boost/math/constants/constants.hpp> #include <boost/multiprecision/cpp_dec_float.hpp> using namespace std ; int main( ) { using boost::multiprecision::cpp_dec_float_50 ; cpp_dec_float_50 num=cpp_dec_float_50( “1234.56593838732623723832”) ; cout << num << endl ; cout<< setprecision(20) << num << endl ; /***Calculating Area of a circle ***/ cpp_dec_float_50 radius=cpp_dec_float_50(“2.145”) ; cout<<“Area =” << boost::math::constants::pi<cpp_dec_float_50>() * radius * radius << endl ; /***Setting the precision up to 50 digits****/ cout<< “Area =” << setprecision(50) << boost::math::constants::pi<cpp_dec_float_50>() * radius * radius << endl ; cin.get(); return 0; }
The output is
1234.5659383873262372
Area =14.454546338982978435
Area =14.45454633898297843499758377255357475776328133576
You can see we have obtained a very precise and accurate value.
Boost is not a bad library(in fact it is the best C++ library) so you can install the library and check the output yourself. And also if you are planning to make a Calculator that can yield a high precision and very accurate value then Boost might come in handy.
Link :Boost
Conclusion
Precision and accuracy in floating point is not a petty issue and it must be given an equal weight of importance as the other C++ features. Since C++ does not provide any library to handle this problem we must turn to a third-party library for solution and Boost is one such library. If you love C++ then having this library on your computer is worth it in every way.