The floating point.
Floating point numbers are the form of real numbers stored in computers. We often need floating point numbers to process decimal point operations. Do you know that floating point numbers also have these operations:
Positive and negative infinity
Unlike integers, floating point numbers do not have the concept of overflow. When the calculation result of a floating point number exceeds a certain range, its value changes to positive infinity or negative infinity according to the symbol of the calculation result. The simplest operation to produce infinity is dividing by 0. For example, the result of 1.0/0.0 is positive infinity, and the result of-1.0/0.0 is negative infinity. Note: A floating point value with the exception of 0 does not produce errors. Only integers are allowed.
The nature of infinity is the same as you think: Except for infinity itself and the NaN mentioned later, any floating point number is smaller than positive infinity and greater than negative infinity. In addition, the infinite addition, subtraction, and division of a non-infinite number, or the result of a non-zero number are all infinite (it is possible to change the number ).
Infinity is useful in certain situations. For example, if you want to find the minimum value of xx, You can initialize the minimum variable to infinity. Alternatively, you can use the price of infinity to indicate that there is no solution.
NaN
NaN is a toxic constant in a floating point number. It satisfies many wonderful properties.
NaN is short for Not a Number. That is to say, NaN indicates that it is not a number. A floating point actually has a number that is not a number. What exactly does it mean?
First, let's see how NaN is generated. NaN corresponds to the "infinitus" in mathematics, such as 0.0/0.0, (1.0/0.0-1.0/0.0) (that is, infinity Minus infinity), 0.0 * (1.0/0.0) (0 multiplied by infinity. That is to say, when the calculation result is uncertain, it simply gives you a "not a number ".
Because NaN is not a number, it satisfies many of the three views. One of its iconic properties is that it is not equal to any number, including itself!
Therefore, when x is NaN, x = x is false!
This is a common method to determine whether a floating point number is NaN. In fact,! Except that the result of = is always true, the comparison between NaN and all floating point values is false. In addition, the result of NaN and any floating point number operations (I .e. addition, subtraction, multiplication, division, and so on) is NaN.
Due to NaN's toxic nature, it can easily cause various bugs. For example, if you want to calculate the Infinity Minus infinity, you will get NaN. Because all of its comparisons are false, your program may have strange behaviors, so you may be puzzled.
Also, if you see the following if statement
if (x < 1.2) { // Do something} else if (x >= 1.2) { // Do something}
You may think that the if statement behind else is redundant. Actually not. This if clause serves to exclude NaN. Especially when x is a function parameter, if the parameter is passed into a NaN, you must be able to handle it correctly.
Of course, NaN also has a positive effect. For example, we can use NaN to indicate "no solution" or "no. We can also take advantage of the fact that it is not equal to any number. For example, if we want to delete a number from the floating point group, we can set it to NaN. Specifically, in C ++, we can use memset (arr, 0xFF, sizeof (arr) to initialize the floating point group to NaN.
Precision Error
Due to limited storage space, it is impossible to store a real number, especially the exact value of an infinite decimal number. In this way, the accuracy error will be generated during the operation.
Let's look at the following code:
for (int i = 1; i < 100; ++i) { double a = 1.0/i; if (a*i != 1.0) cout << " " << i;}cout << endl;
If there is no accuracy error, the above program should output nothing. But in fact it will output 49 and 98. This is an equal judgment error caused by precision errors.
Therefore, whether two floating point numbers are equal cannot be directly determined, but the absolute value of the difference between two numbers should be smaller than a very small number (for example, 1e-7, 7 represents the exact decimal place) as a condition.
const double eps = 1e-7;cout << "inexact result with double:";for (int i = 1; i < 100; ++i) { double a = 1.0/i; if (!(fabs(a*i - 1.0) < eps)) cout << " " << i;}
This code won't have any output.