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 returns true, correct
$c-$b==$a returns false, error
Why is this happening?
After the operation, the actual returned content when the precision is 20 digits 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 comparing with 0.1 returns false
This problem occurs because floating-point number calculations involve precision. When floating-point numbers are converted to binary, precision may be lost.
The integer part is divided by and the remainder is taken by 2Method
The decimal part is multiplied by RoundingMethod
For example:Convert 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 is smaller than 2, so there is no need to calculate it. The binary system of the integer 8 is 1000
The decimal part is 0.5
0.5x2 = 1.0
Since the decimal part is 0 after rounding, there is no need to calculate anymore
Decimal 0.5 The binary representation of 0.1
8.5 is 1000.1
Calculate the binary representation 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 that, the loop continues. When the interception accuracy is When N, the number after N will be rounded off, resulting in loss of accuracy.
In the above example, the precision of 0.9 is lost when converted to binary, resulting in errors during comparison.
So never believe that a floating point number is accurate to the last digit, and never compare two floating point numbers for equality.
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. Use high-precision calculation methods
When performing calculations first, use high-precision calculation methods to ensure that accuracy is not lost.
The method of high-precision operation is as follows:
bcadd Add two high-precision numbers
bccomp Compare two High-precision numbers, return -1,0,1
bcp Divide two high-precision numbers
bcmod Find the remainder of high-precision numbers
bcmul Multiply two high-precision numbers
bcpow Find the power of a high-precision number
bcpowmod Find the modulus of the power of a high-precision number
bcscale Configure the default number of decimal points, equivalent to "scale=" in Linux bc
bcsqrt Find the square root of a high-precision number
bcsub Combine two high-precision Number subtraction
Example:
<?php$a = 0.1;$b = 0.9;$c = 1; var_dump(($c-$b)==$a); // falsevar_dump(bcsub($c, $b, 1)==$a); // true?>
This article explains the PHP floating point number comparison method. For more related content, please pay attention to the PHP Chinese website.
Related recommendations:
Explanation on the method of exporting query results to csv through mysql
##php array_push and $arr[] =$value performance comparison
How to use php to set up a session that strictly controls the expiration time
The above is the detailed content of An explanation of PHP floating point number comparison method. For more information, please follow other related articles on the PHP Chinese website!