为什么 PHP 把字母 E 的字符串转换成数字?

为什么下面的语句返回 true

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

我还尝试过在字符串周围使用单引号。我可以让它评估到 false的唯一方法是使用 ===操作符而不是 ==

我的猜测是 PHP 将其视为某种方程式,但它似乎有点奇怪。

有人能解释一下吗?

6323 次浏览

"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.

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.

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

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

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.

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.

Other answers have noted this, but the PHP manual has made this explicit now. PHP sees any string with an E bounded by numbers as scientific notation

EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})

As you can see, this is case insensitive (E or e). Where this becomes a gotcha is in weak type string comparisons

var_dump("2E1" == "020"); // true

2E1 is really 2 * (10 ^ 1), and that works out to 20. Insert any other letter there and it will return the expected false. From the question

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

That works out to

608 * (10 ^ -4234) == 272 * (10 ^ -3063)

Neither number can be represented by PHP (as JvdBerg noted), so they are converted to 0