2012-09-17 165 views
3

Reffer this link比較運算符

我知道操作數與字符串類型轉換成數字,然後按普通數學

但是看到這些示例代碼:

echo intval(1e1);  // 10 
var_dump("1e1" == 10); // true, and it's ok 

echo intval(0x1A);  // 26 
var_dump("0x1A" == 26); // true, and it's ok 

echo intval(042);  // 34 
var_dump("042" == 34); // fasle, Why ?!!! 

爲什麼最後的代碼返回false。

+1

'var_dump(intval(042)== 34);'作品桃色 – Kermit

+1

[類型問題](http://codepad.viper-7.com/WM1kgX)! – DaveRandom

回答

9

的八進制表示這是因爲字符串到數字的轉換在PHP是基於一些古老的C函數 - strtod。和它的規則爲follows

串(的初始部分)的預期形式是可選 前導空白由isspace(3),可選的加 (「+」)或減去作爲識別號(「 - 」),然後或者(ⅰ)一個十進制數,或 (ⅱ)的十六進制數[...]

的十進制數由十進制數字 可能含有一個基數字符非空序列的(小數點, 區域設置相關,通常爲'。'),可選的是後跟小數點 指數。十進制指數由一個'E'或'e'組成,後面跟着一個可選的加號或減號 ,後面跟着一個非空序列 十進制數字,並表示乘以10的冪。[...]

十六進制數由「0x」或「0X」,隨後的可能含有一個基數字符十六進制數字的非空子 序列, 任選地隨後通過二進制指數。 [...]

如您所見,'1e1'字符串具有非空序列'1',後跟小數指數'e1'。因此,它會被轉換成十進制數 - 並變爲10.

「0x1A的」字串遵循用於十六進制數的規則,並且將相應地轉化成26。但是由於沒有關於十八進制數字的具體規則,所以'042'將被轉換爲普通小數 - 並且變成42.這當然不等於34。

這不應與數字文字如何由PHP本身解析相混淆。以0開頭的數字文字被認爲代表十進制數字。因此,intval(042)intval(34)基本相同 - 但與intval("042")不同。

+0

有趣,感謝分享。這意味着二進制文字也沒有被正確轉換。 – rodion

+0

很高興看到某種真實的原因,並將一個恰當的解釋放入一次+1的答案中。 – DaveRandom

1

我不知道所有的數學魔神但是,

因爲前兩個例子是清楚你正在嘗試做的..它轉換爲指數,並將其轉換爲十六進制。 但第三個解決方案是不是你在做什麼明確的,所以它轉換爲42 想想其他方式.. 您試圖solvve問題,由於某種原因,「042」不等於42。你會很困惑

因此,使用你所需要的,如果你需要的042,然後轉換爲int一個int表示,但如果它是一個字符串,不要指望它的工作的方式。

+0

'echo intval(042);'是34? – Kermit

+0

是的,但在這種情況下,由於您正在用零填充它,因此很明顯,您正在使用八進制表示法。我認爲這很容易理解,如果你想要一個整型值將其轉換爲一個int,如果你不把它留給一個字符串。 – Kris

3

那怎麼PHP卷。這是因爲當你指定一個字符串轉換,它被轉換爲數字,你的情況,第一1e1意味着1 exponent 1,該0x1A是十六進制表示的最後一份042本身是一個數字,它被轉換爲42intval(042)手段34.整數

+0

我想這裏真正的問題是:爲什麼隱式轉換方面的基數16(用0x開頭的字符串表示),但不尊重基數8(用以零開頭的字符串表示)? – rodion

+0

@rodion因爲PHP很煩人而且不一致。我肯定會有一些無意義的理由被深埋在PHP/FI的沙地中。 – DaveRandom

+1

因爲我認爲很多人會爲了「042」!= 42而感到困惑並提交bug。用0x和e表示清楚它在做什麼。 – Kris