Better the double You Know
One of the criteria for choosing a floating point datatype is the number of decimal digits it can store without precision loss. For example, suppose your application must support decimal numbers with up to 16 digits. Should you use
double, long double or perhaps there's no escape from using a user-defined type? To answer this question, use the
numeric_limits::digits10 constant which reports the number of decimal digits that a type can represent without loss of precision:
cout<<numeric_limits<double>::digits10<<endl;//output: 15
It appears that
double doesn't offer this precision. Will
long double save the day?
cout<<numeric_limits<long double>::digits10<<endl; // 18
Yes, it will.
Notice that digits10 works with integral types as well:
cout<<numeric_limits<long>::digits10<<endl; //output: 9
Max and Min
The maximum and minimum values that a type can represent are obtained by calling the
numeric_limits::max() and
numeric_limits::min() member functions:
cout<<numeric_limits<int>::max()<<endl;// 2147483647
<limits> Unlimited
In
IEC 559-compliant implementations, floating point datatypes have an agreed-upon value which represents "not a number", or
NaN. NaN is a special encoding that represents an illegal number. This can be the result of an illegal instruction, or it could be deliberately chosen to indicate a value that should be ignored, discarded etc. A NaN is said to be quiet if its presence in an expression doesn't raise a
signal. Otherwise, it's a signaling NaN.
The following example checks which type of NaN is supported on the target platform and then assigns that NaN value to a variable:
double d=0;
if(numeric_limits<double>::has_quiet_NaN)
d=numeric_limits<double>::quiet_NaN();
else if (numeric_limits<double>::has_signaling_NaN)
d=numeric_limits<double>::signaling_NaN();
else cerr<<"NaN for double isn't supported";
Infinity is another special case. Infinity is the result of division by zero or other operations. The following code checks whether the target machine defines a special infinity code and then assigns this value to a variable:
float f=0;
if(numeric_limits<float>::has_infinity)
f=numeric_limits<float>::infinity();
else cerr<<"infinity for float isn't supported";