Floating point number in the conversion process will have errors, so the floating-point number can not directly compare its size, generally in comparison with two floating-point number is compared between their difference, if the difference between two numbers in an acceptable range, then, we think the two floating-point numbers are equal. This article mainly introduced the PHP floating-point comparison method, has the very good reference value. Let's take a look at the little series.
Floating-point arithmetic precision problem
First look at an example:
<?php$a = 0.1; $b = 0.9; $c = 1;var_dump (($a + $b) = = $c); Var_dump (($c-$b) = = $a);? >
$a + $b = = $c return true, correct
$c-$b = = $a return false, error
Why is that?
After the operation, the exact content returned when the precision is 20 bits is as follows:
<?php$a = 0.1; $b = 0.9; $c = 1;printf ("%.20f", $a + $b); 1.00000000000000000000printf ("%.20f", $c-$b); 0.09999999999999997780?>
$c-$b is 0.09999999999999997780, so the comparison with 0.1 returns false
This problem occurs because the floating-point calculation involves precision, which can result in loss of precision when the floating-point number is converted into binary.
Floating point to Binary binary method
The integer part is divided by 2 to take the remainder method
The number of decimal points is multiplied by 2 rounding Method
Example: Converting the number 8.5 to binary
The integer part is 8
8/2=4 8%2=0
4/2=2 4%2=0
2/2=1 2%2=0
1:2 Small, so no calculation is required, and the binary of integer 8 is
The fractional part is 0.5
0.5X2 = 1.0
The number of decimal parts after rounding is divided into 0, so no further calculation is required.
Decimal 0.5 binary is 0.1
8.5 binary for 1000.1
Computes the binary of the number 0.9
0.9x2=1.8
0.8x2=1.6
0.6x2=1.2
0.2x2=0.4
0.4x2=0.8
0.8x2=1.6
.... After a continuous loop, when the intercept accuracy is n, the number after n is discarded, resulting in loss of precision.
In the previous example, 0.9 was lost in the conversion to binary, resulting in an error when comparing.
So never believe that the float is accurate to the last one, and never compare two floating-point numbers for equality.
A method of correctly comparing floating-point numbers
1. Use the round method to process and then compare
Example:
<?php$a = 0.1; $b = 0.9; $c = 1;var_dump (($c-$b) = = $a); Falsevar_dump (Round ($c-$b), 1) ==round ($a, 1)); True?>
2. Using a high-precision operation method
In the first operation, a high-precision operation is used to ensure that the accuracy is not lost.
The method of high precision operation is as follows:
Bcadd adds two high-precision numbers
Bccomp compares two high-precision numbers, returning -1,0,1
bcp divides two high-precision numbers
Bcmod seeking high precision digital remainder
Bcmul Multiply two high-precision numbers
Bcpow High Precision digital exponentiation
Bcpowmod seeking modulus of high precision digital exponentiation
Bcscale Configure the default number of decimal places, equivalent to "scale=" in Linux BC
bcsqrt to find the square root of high precision number
bcsub to subtract two high-precision numbers
Example:
<?php$a = 0.1; $b = 0.9; $c = 1;var_dump (($c-$b) = = $a); Falsevar_dump (Bcsub ($c, $b, 1) = = $a); True?>