/*
====================================================================
Title: Safe Floating-Point Comparison in PHP
Purpose:
Demonstrates how to compare floating-point values safely
using a tolerance (epsilon) instead of the == operator.
Why not use == ?
Floating-point numbers are stored as binary approximations.
Some decimal values cannot be represented exactly, which
leads to small rounding errors.
Example:
0.1 + 0.2 != 0.3
Although mathematically equal, the actual binary values
may differ slightly.
====================================================================
*/
/**
* Compares two floating-point values using a tolerance.
*
* Parameters:
* $a First value
* $b Second value
* $epsilon Maximum allowed difference
*
* Returns:
* true -> Values are considered equal
* false -> Values are different
*
* This simple approach is suitable for many applications.
*/
function approximatelyEqual(float $a, float $b, float $epsilon): bool
{
return abs($a - $b) <= $epsilon;
}
/*
* Classic floating-point precision example.
*/
$x = 0.1 + 0.2;
$y = 0.3;
/*
* Define an acceptable tolerance.
* Choose a value appropriate for your application.
*/
$epsilon = 1e-9;
echo "================================================\n";
echo " Safe Floating-Point Comparison in PHP\n";
echo "================================================\n\n";
/*
* Display many decimal places so precision differences
* become visible.
*/
printf("x = %.17f\n", $x);
printf("y = %.17f\n", $y);
echo "\n";
/*
* BAD PRACTICE:
* Direct comparison using ==.
*
* Tiny rounding errors can cause this comparison
* to produce unexpected results.
*/
if ($x == $y) {
echo "Direct comparison (==): Equal\n";
} else {
echo "Direct comparison (==): Not Equal\n";
}
echo "\n";
/*
* GOOD PRACTICE:
* Compare using a tolerance (epsilon).
*/
if (approximatelyEqual($x, $y, $epsilon)) {
echo "approximatelyEqual(): Equal\n";
}
/*
run:
================================================
Safe Floating-Point Comparison in PHP
================================================
x = 0.30000000000000004
y = 0.29999999999999999
Direct comparison (==): Not Equal
approximatelyEqual(): Equal
*/