Wrong PHP string equality - php

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.

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.

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

Try using $a === $b instead; you should never use == for string comparison.

Read PHP: Comparison Operators
If you compare a number with a string or the comparison involves
numerical strings, then each string is converted to a number and the
comparison performed numerically. These rules also apply to the switch
statement. The type conversion does not take place when the comparison
is === or !== as this involves comparing the type as well as the
value.
Others have recommended BC Math, but if you are doing floating point comparisons, the traditional way of comparing numbers is to see if they are the same to a reasonable error level
$epsilon = 1.0e-10;
if (abs($a - $b) < $epsilon) then {
// they're the same for all practical purposes
}

You should not to compare a float variable like that.
Try this:
bccomp($a, $b, 26)

Related

PHP xor returns wrong value

Using php 7.1.0 I'm running this little test:
<?php
$a = true;
$b = true;
$value = $a xor $b;
if ($value == true) {
print "bad!\n";
} else {
print "good\n";
}
and it's coming back and saying bad. Why? An xor of two true values should be FALSE, not true.
The problem is operator precedence. The xor operator has lower precedence than =, so your statement is equivalent to:
($value = $a) xor $b;
You need to write:
$value = ($a xor $b);
or
$value = $a ^ $b;
The ^ operator is bit-wise XOR, not boolean. But true and false will be converted to 1 and 0, and the bit-wise results will be equivalent to the boolean results. But this won't work if the original values of the variables could be numbers -- all non-zero numbers are truthy, but when you perform bit-wise XOR with them you'll get a truthy result for any two numbers that are different.
See the PHP Operator Precedence Table
See the related Assignment in PHP with bool expression: strange behaviour

Usage of comparison operator after assigning variable

I've seen comparison operators used straight after assigning values to variables in codes such as this:
($i = array_search($v, $b)) !== false // If $v is not in array, outputs false
Or something like this:
$n = 5 <= 5;
echo $n; // Outputs 1;
In the first example, does the comparison operator directly compare the value to array_search(...) or does it compare it to $i, since both of them are in brackets? Would it make a difference if there were no brackets around "$i = array_search(...)?
I've tried looking in the PHP manual on comparison operators, but it does not seem to mention using comparison operators in this way.
Also, in the second example, if there are no brackets, is the comparison operator comparing the value to 5 or to $n?
Could someone please link any documents or articles relating to the usage of comparison operators after assigning variables?
does the comparison operator directly compare the value to array_search(...) or does it compare it to $i
It assigns the value from array_search to $i first, and then evaluates a comparison to that value second.
In your example, array_search will return false on failure.
if( ($i = array_search($v, $b)) !== false ){}
Is totally equivalent to:
$i = array_search($v, $b);
if($i !== false){}
Or:
if( array_search($v, $b) !== false ){}
It's just a convenient shortcut to also assigning the value of $i for use later.

Compare floating numbers in PHP

I want to compare two floating numbers to see if $a is greater than $b.
So if:
$a = 1.23.94
$b = 1.23.90
If a is greater than b i want to echo "whatever".
Also need to allow for possibility of a number being 1.23.100 and comparing.
Thanks
to simply compare the two variables
if($a > $b) {
echo "whatever";
}
this link also may help you.
http://php.net/manual/en/language.types.float.php
notice that php has its floating point precision

can === and != be used interchangably?

Can the relational operator === (used for identical) be used interchangeably with the != operator" and get the same results? Or will I eventually run into issues later down the road when I do larger programs?
I know I will get the same results in the example below, will this always be true?
//example 1
<?php
$a = 1; //integer
$b = '1'; //string
if ($a === $b) {
echo 'Values and types are same';
}
else {
echo 'Values and types are not same';
}
?>
// example 2
<?php
$a = 1; //integer
$b = '1'; //string
if ($a != $b) {
echo 'Values and types are not same';
}
else {
echo 'Values and types are same';
}
?>
Short answer is, no, you can't interchange them because they check for different things. They are not equivalent operators.
You'll want to use !==
It basically means both values being compared must be of the same type.
When you use ==, the values being compared are typecast if needed.
As you know, === checks the types also.
When you use !=, the values are also typecast, whereas !== checks the values and type, strictly.
You're essentially asking whether !($a != $b) will always be identical to $a === $b. The simple answer is: no. !($a != $b) can be boiled down to $a == $b, which is obviously not the same as $a === $b:
php > var_dump(!('0' != 0));
bool(true)
php > var_dump('0' === 0);
bool(false)
!== is obviously the opposite of ===, so !($a !== $b) will always be identical to $a === $b.

What does "===" mean? [duplicate]

This question already has answers here:
How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
(13 answers)
Closed 4 months ago.
I've noticed someone using the PHP operator === which I can't make sense out of. I've tried it with a function, and it corresponds in crazy ways.
What is the definition of this operator? I can't even find it in the declaration of PHP operators.
$a === $b (Identical)
TRUE if $a is equal to $b, and they are of the same type. (introduced in PHP 4)
PHP Docs
http://www.php.net/ternary
$a == $b Equal TRUE if $a is equal to $b, except for (True == -1) which is still True.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
> "5" == 5;
True
> "5" === 5;
False
You can read here, short summary:
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
In PHP you may compare two values using the == operator or === operator. The difference is this:
PHP is a dynamic, interpreted language that is not strict on data types. It means that the language itself will try to convert data types, whenever needed.
echo 4 + "2"; // output is 6
The output is integer value 6, because + is the numerical addition operator in PHP, so if you provide operands with other data types to it, PHP will first convert them to their appropriate type ("2" will be converted to 2) and then perform the operation.
If you use == as the comparison operator with two operands that might be in different data types, PHP will convert the second operand type, to the first's. So:
4 == "4" // true
PHP converts "4" to 4, and then compares the values. In this case, the result will be true.
If you use === as the comparison operator, PHP will not try to convert any data types. So if the operands' types are different, then they are NOT identical.
4 === "4" // false
$x == $y is TRUE if the value of the $x and $y are same:
$x = 1; //int type
$y = "1"; //string type
if ($x == $y) {
// This will execute
}
$x === $y TRUE if the value of the $x and $y are same and type of $x and $y are same:
$x = 1; //int type
$y = "1"; //string type
if ($x === $y) {
// This will not execute
}
You'll see this operator in many dynamically typed languages, not just PHP.
== will try to convert whatever it's dealing with into types that it can compare.
=== will strictly compare the type and value.
In any dynamically typed language you have to be careful with ==, you can get some interesting bugs.
The ternary === is less convenient, but it's safer. For comparisons you should always give some additional thought to whether it should be === or ==
The triple equals sign === checks to see
whether two variables are equal and of the same type.
For PHP, there many different meanings a zero can take
it can be a Boolean false
it could be a null value
It could really be a zero
So === is added to ensure the type and the value are the same.
See Double and Triple equals operator in PHP that I got for googling on "PHP three equals operator".
At one point it says that:
A double = sign is a comparison and tests whether the variable / expression / constant to the left has the same value as the variable / expression / constant to the right.
A triple = sign is a comparison to see whether two variables / expresions / constants are equal AND have the same type - i.e. both are strings or both are integers.
It also gives an example to explain it.
"===" matching the value in the variable as well as data type of the variable.

Categories