After I wrote the first article on Floating Point Number comparison and floating point memory structure
There are new ideas for comparing floating point numbers
Let's first look at positive numbers.
According to the IEEE memory structure, the index is at a high level and the ending number is at a low level.
When the memory structure of floating point numbers is compared according to integers, the situation is also true.
Therefore, if we compare them here, the efficiency of using them as integers will be very high, for example
Float F1 = 1.23;
Float F2 = 1, 1.24
F1> F2 was established
(Int &) F1> (Int &) F2 is also true
Furthermore, by carefully studying the floating point structure of IEEE, we can find that the floating point Precision problem mentioned in floating point comparison-not all floating point numbers can be accurately expressed.
The floating point numbers that can be precisely expressed are actually limited, that is, the IEEE enumerated for various situations are 2 ^ 32. What cannot be expressed occupies the majority
In the case of 32-bit IEEE, the ending number is 23 bits (meaning that the first digit is 1)
For floating-point numbers that can be accurately expressed, if we consider these 23 digits as integers, adding 1 means we can find the smallest floating-point number larger than the current floating-point number.
On the contrary, we calculate the difference between two floating point numbers and corresponding integers, the obtained integer indicates how many floating-point numbers can actually be expressed between two floating-point numbers (the corresponding indexes are the same, which is also effective when the indexes are different)
In this way, we can use (Int &) F1-(Int &) F2 to compare the two positive floating point numbers.
The result of the difference is actually a relative error.
This relative error is not equivalent to the relative error in the general sense.
It expresses the number of floating-point numbers that can be accurately expressed between two floating-point numbers.
In this way, it is more effective to control the comparison between two floating point numbers by specifying this threshold.
For two positive floating point numbers
Bool isequal (float F1, float F2, int absdelta)
{
If (ABS (Int &) F1-(Int &) F2) <absdelta) return true;
}
ABS instead of FABs is used here. The calculation gap in ASM is also very large.
The comparison of two negative numbers is the same.
Only the integer corresponding to the negative memory is added with 1, and the corresponding result is a smaller negative number.
However, there is no direct comparison between negative numbers and integers, because according to the IEEE Memory Structure
The positive and negative numbers are different, and the corresponding integers cannot be consecutive.
The smallest positive number is 0, and the corresponding integer is 0x00000000.
The smallest negative value is-0, and the corresponding integer is 0x80000000.
Don't be surprised-0
There are two 0's In the IEEE expression. One is + 0 and the other is-0.
Interestingly, + 0 and-0 are equal according to the F1 = F2 judgment.
By comparison, we can find that,
+ 0 and Positive floating point numbers can be directly compared by converting them into integers.
-0 and negative floating point numbers can be directly compared by converting them into integers.
If we can connect them, the direct comparison of the entire integer method will be complete.
By comparing the structure of negative numbers, we can find a simple method:
Subtract-0 from the integer corresponding to the negative memory, and they are connected consecutively.
In addition, the better result is that after all the negative numbers are subtracted, the corresponding integers are also negative.
In this way, the entire integer comparison becomes continuous, and it is valid throughout the floating point range.
The final comparison algorithm is:
// Function: bool isequal (float F1, float F2, int absdelta)
// Function: compare whether two floating point numbers are similar
// Input: two floating point numbers involved in the comparison between F1 and F2
// How many floating-point numbers are allowed between two floating-point numbers in absdelta? The number of floating-point numbers that can be accurately expressed exists, which is equivalent to the relative error.
// Output: True, two floating point numbers are equal; false two floating point numbers are not equal
// Note: Only applicable to the IEEE 32-bit floating point number Structure
Bool isequal (float F1, float F2, int absdelta)
{
Int I1, I2;
I1 = (F1> 0 )? (Int &) F1): (Int &) F1-0x80000000 );
I2 = (F2> 0 )? (Int &) F2): (Int &) F2-0x80000000 );
Return (ABS (i1-i2) <absdelta )? True: false;
}