Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong PHP string equality

For some reason, PHP decided that if:

$a = "3.14159265358979326666666666"

$b = "3.14159265358979323846264338"

$a == $b is true.

Why is that, and how can I fix that?

It ruins my code.

like image 725
user3457026 Avatar asked Mar 28 '14 09:03

user3457026


People also ask

Can you use == to compare strings in PHP?

The assignment operator assigns the variable on the left to have a new value as the variable on right, while the equal operator == tests for equality and returns true or false as per the comparison results. Example: This example describes the string comparison using the == operator.

What is === in PHP?

=== Operator: This operator is used to check the given values and its data type are equal or not. If yes, then it returns true, otherwise it returns false.

How check string is equal or not in PHP?

The strcmp() function compares two strings. Note: The strcmp() function is binary-safe and case-sensitive. Tip: This function is similar to the strncmp() function, with the difference that you can specify the number of characters from each string to be used in the comparison with strncmp().

How PHP compares data of different types?

How PHP compares values. PHP has a feature called “type juggling”, or “type coercion”. This means that during the comparison of variables of different types, PHP will first convert them to a common, comparable type.


2 Answers

The Problem

PHP converts strings (if possible) to numbers (source). Floating points have a limited precision (source). So $a == $b because of rounding errors.

The Fix

Use === or !==.

Try it

<?php

$a = "3.14159265358979326666666666";
$b = "3.14159265358979323846264338";

if ($a == $b) {
    echo "'$a' and '$b' are equal with ==.<br/>";
} else {
    echo "'$a' and '$b' are NOT equal with ==.<br/>";
}

if ($a === $b) {
    echo "'$a' and '$b' are equal with ===.<br/>";
} else {
    echo "'$a' and '$b' are NOT equal with ===.<br/>";
}
?>

Results in

'3.14159265358979326666666666' and '3.14159265358979323846264338' are equal with ==.
'3.14159265358979326666666666' and '3.14159265358979323846264338' are NOT equal with ===.

Note

When you want to do high precision mathematics, you should take a look at BC Math.

like image 176
Martin Thoma Avatar answered Sep 27 '22 22:09

Martin Thoma


You could use === in the equality test.

$a = "3.14159265358979326666666666";
$b = "3.14159265358979323846264338";

if($a===$b)
{
    echo "ok";
}
else
{
    echo "nope";
}

This code will echo nope.

Comparing with == is a loose comparison, and both strings will be converted to numbers, and not compared right away.

Using === will perform a string comparison, without type conversion, and will give you the wanted result.

You can find more explanations in the PHP manual:

  • PHP type comparison tables

  • Comparison Operators

like image 43
Theox Avatar answered Sep 27 '22 23:09

Theox