Reputation: 35
I have the weirdest bug that I just can't figure out.
I'm looping though values and checking if they equal to a float.
The weird thing is it works fine for some values but not others which has my brain melted. It "matches" when I do a straight comparison but when $num1 is created in the loop it doesn't like it anymore
For example 0.1, 0.2 both return matches but 0.3 does not!?
$num1 = 0.3;
$num2 = 0.3;
var_dump($num1);
var_dump($num2);
if ($num1 == $num2) {
echo "*** MATCH ***<br>";
} else {
echo "NO MATCH<br>";
}
echo "<hr>";
for ($num1=0; $num1 < 0.6; $num1 = $num1 + 0.1) {
var_dump($num1);
var_dump($num2);
if ($num1 == $num2) {
echo "*** MATCH ***<br>";
} else {
echo "NO MATCH<br>";
}
echo "<hr>";
}
The above code returns
float(0.3) float(0.3) *** MATCH ***
int(0) float(0.3) NO MATCH
float(0.1) float(0.3) NO MATCH
float(0.2) float(0.3) NO MATCH
float(0.3) float(0.3) NO MATCH
float(0.4) float(0.3) NO MATCH
float(0.5) float(0.3) NO MATCH
If I change the $nums to 0.2 for example then it works!
float(0.2) float(0.2) *** MATCH ***
int(0) float(0.2) NO MATCH
float(0.1) float(0.2) NO MATCH
float(0.2) float(0.2) *** MATCH ***
float(0.3) float(0.2) NO MATCH
float(0.4) float(0.2) NO MATCH
float(0.5) float(0.2) NO MATCH
I'm at a loss!
Can someone else run this code to see if they get the same result please?
Thanks in advance
TempPeck
Upvotes: 0
Views: 84
Reputation: 16423
I've converted the PHP into JS which may help to visualise the issue:
let num1 = 0.3;
let num2 = 0.3;
if (num1 == num2) {
console.log(`num1: ${num1} num2: ${num2} *** MATCH ***`);
} else {
console.log(`num1: ${num1} num2: ${num2} NO MATCH`);
}
for (num1 = 0; num1 < 0.6; num1 += 0.1) {
if (num1 == num2) {
console.log(`num1: ${num1} num2: ${num2} *** MATCH ***`);
} else {
console.log(`num1: ${num1} num2: ${num2} NO MATCH`);
}
}
This is a well-known issue with floating-point numbers and the way that they are stored.
This answer is particularly good as it helps to visualise the problem.
Essentially, floating-point numbers are imprecise in that 0.3 may actually be 0.299999999999999999999993654 or 3.0000000000000000000001284 (this is not the actual values just an illustration of the problem). Comparing one to the other is not as easy as using ==
.
Upvotes: 1