In C + +, each built-in data type has a different attribute, and the information contained in it is very important to the design program, and here's how the,<limits> library can help access that information.
There are about 10 distinct integer types and more than 3 floating-point types in C + +. Each data type has different numeric properties, such as range of values, maximum digits that can be represented, or the respective precision, etc., which are extremely important to finance, science, graphics, digital signal processing and other programs. This article discusses how to use the <limits> library to get the numeric properties of these basic data types in the program.
"How many bits can be stored in a double type?" "," What is the maximum positive number that signed long can represent? "If the answers to these questions are important to your program, how do you get the answer in a convenient and systematic way?" The answer is: Use standard <limits> library.
Floating-point movement
The precision of floating-point data types in C + + is limited, and some hardware-related attributes result in truncation and rounding of floating-point data types. Now, you can see why the results of 2.0/3.0 are probably 0.66666666666666663, "digital noise" is usually the source of most bugs, see the following example:
double d1=2., d2=3.;
d1/=d2; // 2/3
if (d1*10==(20./d2)) //条件本应该是"真"的,但,哎!
{
//永远不可能执行到的代码
do_equal();
}
The lines of code in curly braces can never be executed, because the expression on both sides of the = = is slightly different, and the result of D1*10 is 6.6666666666666661, and 20./ The result of the D2 is 6.6666666666666670, and it is the truncation and approximation of this floating-point algorithm that leads to this difference. Here, you can use a calibration integer, but sometimes it's not a good solution, imagine a spreadsheet that calculates a complex number formula-it must use a floating-point type, in which case a small positive (epsilon) constant is the problem, Small positive numbers are usually expressed as the difference between a minimum value of 1 and a 1 for a given data type. For example, a small positive number for the double type is:
#include <iostream>
#include <limits>
using namespace std;
cout << numeric_limits<double>::epsilon( ) << endl; //输出:2.22045e-016
To reduce the impact of digital noise in if statements, you can replace the = = Operator with an expression that checks for a roughly equal two value. Such as:
if ( ((d1*10)-(20.0/d2)) <= numeric_limits<double>::epsilon())
{
do_equal();
}
If the double type (d1*10)-(20.0/D2) result is not greater than a small positive number, then it is almost zero, so two subexpression results are equal, and applying this technique can effectively reduce the wrong threshold. For example, if One-zero or smaller numbers don't matter to your program, try the following tips:
const double BILLIONTH=1./1000000000;
if ( ((d1*10)-(20.0/d2)) <= BILLIONTH)
Keep in mind that small positive numbers are the minimum deviation limit.
Better than double
The standard for selecting a floating-point data type is the maximum number of decimal digits that it can store in the case of lossless precision. For example, suppose your program must support a decimal number of 16 digits, should a double, long double or a user-defined type be used? To answer this question, use the numeric_limits::d IGITS10 constant, which tells you the maximum number of decimal digits a type can represent in the case of precision damage:
cout<<numeric_limits<double>::digits10<<endl;//输出:15
It looks like double does not support this precision, so what about long double?
cout<<numeric_limits<long double>::digits10<<endl; //输出:18
Yes, it's OK. Note that DIGITS10 also applies to integer numbers:
cout<<numeric_limits<long>::digits10<<endl; //输出:9
Maximum value and minimum value
The maximum and minimum values are the values that are obtained by invoking Numeric_limits::max () and Numeric_limits:min () for the corresponding type:
cout<<numeric_limits<int>::max()<<endl;// 2147483647
Unlimited <limits>
In the IEC 559 specification implementation, the floating-point data type can be expressed as "not a number" or Nan. Nan is a special type of code that represents an illegal number that can be produced by an illegal instruction or indicates a value that should not be ignored. If nan in the expression does not emit a "signal", it is a "quiet" state; otherwise, it is a "signal" Nan. The following example checks which Nan type is supported on the target platform and assigns the value of Nan 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 a special case in which it is usually produced by a 0 addition or other operation. The following example code checks whether a special infinite code is defined on the target platform and 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";