After seeing many PHP questions about comparing the equality of floats where the answer is to simply choose an arbitrary value for Epsilon and then do if( abs($a-$b) < 0.000001 )
.
The trouble is that Epsilon is typically much smaller than the values people tend to choose [2.22e-16 on my machine] and is actually quite simple to calculate:
$macheps = (float) 1.0;
do {
$macheps /= (float) 2.0;
} while( (float) (1.0 + ($macheps/2.0)) != 1.0 );
printf("Epsilon: %0.25f\n", $macheps);
C++ has std::numeric_limits<double>::epsilon()
, Python has sys.float_info.epsilon
, so why does PHP leave it up in the air?
Because floating point arithmetic is different from real number arithmetic. Bottom line: Never use == to compare two floating point numbers. Here's a simple example: double x = 1.0 / 10.0; double y = x * 10.0; if (y !=
Epsilon comparisonsbool isEqual = fabs(f1 – f2) <= epsilon; With this calculation we can express the concept of two floats being close enough that we want to consider them to be equal.
The is_float() function checks whether a variable is of type float or not. This function returns true (1) if the variable is of type float, otherwise it returns false.
The EPSILON property has a value of approximately 2.2204460492503130808472633361816E-16 , or 2-52. This is the smallest value that can be added to 1 to get a distinct number, because double precision floating point format only has 52 bits to represent the mantissa, and the lowest bit has a significance of 2-52.
I know this is an old question, but as of PHP 7.2 it is provided.
PHP_FLOAT_EPSILON
(float)
Smallest representable positive number x, so that x + 1.0 != 1.0. Available as of PHP 7.2.0.
See http://php.net/manual/en/reserved.constants.php
C++'s std::numeric_limits<double>::epsilon()
was never intended to be used in place of 0.000001
in a formula of the style abs($a-$b) < 0.000001
. For instance, with most C++ compilation platforms, fabs(x - 2.5) < std::numeric_limits<double>::epsilon()
is equivalent to x == 2.5
, because std::numeric_limits<double>::epsilon()
is a representation of the double
definition near 1
.
Some programmers may need to compare floating-point numbers up to some value, but that value has little reason to be related to the definition of the floating-point format near 1, so that's not a good reason to provide that constant in the language. Instead, the value should come either from requirements (“as small as needed”) or by inference (“the floating-point results can be 0.003 from the real result, so fabs(x - 2.5) < 0.003
will never be false if the real result can be 2.5”).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With