104

Possible Duplicate:
php == vs === operator
How do the equality (== double equals) and identity (=== triple equals) comparison operators differ?

Why does the following statement return true?

"608E-4234" == "272E-3063"

I have also tried this with single quotes around the strings. The only way I can get it to evaulate to false is by using the === operator instead of ==

My guess is PHP is treating it as some sort of equation but it seems a bit of a strange one.

Can anybody elaborate?

Community
  • 1
  • 1
Andy
  • 4,462
  • 5
  • 31
  • 53
  • 5
    echo 608E-4234 = 0; echo 272E-3063 = 0; 0==0 –  Sep 26 '12 at 09:22
  • 3
    what does http://php.net/strcmp say? – Bokw Sep 26 '12 at 09:22
  • 14
    [PHP is weakly/loosely typed](http://stackoverflow.com/questions/467871/what-is-a-loosely-typed-language). Depending on context, what you claim is a string, is something else in fact. So better use `===` if you want to compare strings. Know your operators. – hakre Sep 26 '12 at 09:25
  • 4
    @Bokw: http://codepad.org/X8MoswuX – hakre Sep 26 '12 at 09:26
  • `strcmp` exists for this very reason, amongst others. – Joseph Earl Sep 26 '12 at 09:32
  • It would be interesting to know, what you assumed first when you encountered the issue. – hakre Sep 26 '12 at 09:37
  • 2
    @hakra I assumed it was taking the hyphen as a subtraction sign. Re-edited my post to fix your bad grammar ;) – Andy Sep 26 '12 at 09:47
  • 3
    Actually, this question is not fully duplicated, it is not just about the problem of `weakly/loosely typed`, but the behavior of PHP's `==` will convert numerical string to a number when compared with `==`, even they are both strings. This behavior is different from javascript, which also has `==` and `===`. – xdazz Sep 27 '12 at 02:17

6 Answers6

109

"608E-4234" is the float number format, so they will cast into number when they compares.

608E-4234 and 272E-3063 will both be float(0) because they are too small.

For == in php,

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.

http://php.net/manual/en/language.operators.comparison.php

Attention:

What about the behavior in javascript which also has both == and ===?

The answer is the behavior is different from PHP. In javascript, if you compare two value with same type, == is just same as ===, so type cast won't happen for compare with two same type values.

In javascript:

608E-4234 == 272E-3063 // true
608E-4234 == "272E-3063" // true
"608E-4234" == 272E-3063 // true
"608E-4234" == "272E-3063" // false (Note: this is different form PHP)

So in javascript, when you know the type of the result, you could use == instead of === to save one character.

For example, typeof operator always returns a string, so you could just use

typeof foo == 'string' instead of typeof foo === 'string' with no harm.

xdazz
  • 149,740
  • 33
  • 229
  • 258
  • 4
    Important bit from the manual about [operator comparations](http://php.net/manual/en/language.operators.comparison.php): *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.* – Carlos Campderrós Sep 26 '12 at 09:28
  • 26
    See also: http://phpsadness.com/sad/47 – nickgrim Sep 26 '12 at 11:38
  • 5
    `Numerical Strings` -> [What.](http://tvtropes.org/pmwiki/pmwiki.php/Main/FlatWhat) Doesn't it make it even harder to write secure applications in PHP. – Sebastian Mach Sep 26 '12 at 13:09
  • 1
    @phresnel Not really. Use `===`, which should be taught in PHP 101 for "compare these values exactly". It's only confusing to people that come from languages without fuzzy comparison, like C and Java. – Izkata Sep 26 '12 at 13:55
  • 1
    @lzkata: That's for sure, but I wouldn't have expected that when I compare two string literals, such things may happen. In other words: I wouldn't have expected that that when I compare two operands of the exact same type, there's a need for the `===` operator. Of course the documentation mentions it, but the doc is also [fuzzy](http://web.archive.org/web/20080228051801/http://www.php.net/manual/en/language.operators.comparison.php), [quite fuzzy](http://web.archive.org/web/20030402111048/http://www.php.net/manual/en/language.operators.comparison.php). – Sebastian Mach Sep 26 '12 at 14:07
  • Ucch. This is a disgusting linguistic quirk. – ncmathsadist Sep 26 '12 at 23:51
  • Testing floats for equality? The thought gives me dyspepsia. – ncmathsadist Sep 26 '12 at 23:52
  • @phresnel Check the JavaScript's ==, it's different from php! So I think this behavior in php is not normal knowledge :) – xdazz Sep 27 '12 at 13:34
20

PHP uses IEEE 754 for floats, and your numbers are so small that they evalue to 0.

See: http://en.wikipedia.org/wiki/IEEE_floating_point

Name        Common name         Base    Digits  E min   E max   
binary32    Single precision        2   23+1    −126    +127        
binary64    Double precision        2   52+1    −1022   +1023       
JvdBerg
  • 21,117
  • 8
  • 31
  • 54
  • 2
    But he wasn't comparing floats, he's comparing strings. So what PHP uses for floats **should** be irrelevant – jalf Sep 26 '12 at 13:45
  • 2
    @jalf php is loosely typed and is converting the values behind the scenes == is evil if you are not familiar with language, if he wanted to compare them as strings he needed to use === or strcmp as others have mentioned. – stoj Sep 26 '12 at 15:51
  • 7
    @stoj yes, but my point is that this answer does not answer the question: it describes the fp representation used by PHP, but it does not state the important fact that "if your string looks like a FP value, it will be converted into a FP value". – jalf Sep 26 '12 at 15:54
13

I think that PHP reads this as a scientific syntax, which will be translated as:

608 x 10^-4234 == 272 x 10^-3063 

PHP interprets this as being 0 = 0.

Ry-
  • 199,309
  • 51
  • 404
  • 420
Mihai Matei
  • 22,929
  • 3
  • 29
  • 46
10

PHP is comparing those strings as floating point numbers, and they both are zero, so you MUST use the === operator,

hakre
  • 178,314
  • 47
  • 389
  • 754
Matteo Tassinari
  • 16,776
  • 5
  • 55
  • 77
  • 2
    As I said in my answer, that is because the two strings are compared as floating point numbers, which are rounded to zero, hence they're **equal** but not **identical** – Matteo Tassinari Sep 26 '12 at 09:26
5

I'm trying to answer. If you are using "===", you also check with the type instead of the value. If you are using "==", you just check the value is the same or not.

you can reference to here and here.

Alfred Angkasa
  • 1,221
  • 3
  • 16
  • 33
3

This is what it is seeing:
http://www.wolframalpha.com/input/?i=608E-4234&dataset=
http://www.wolframalpha.com/input/?i=272E-3063

As they don't fit into the variable, they both equate to 0, or whatever default value php chooses, and therefore are equivalent.

Joebone
  • 550
  • 3
  • 16