2012-03-08 16 views
9

有一些奇怪的行爲我想知道如果有人能爲我清理。PHP中的十六進制否定,有趣的行爲

檢查出來

$hex = 0x80008000; 

print_r(decbin(intval($hex)) . '<br/>'); 
print_r(decbin($hex)); 

輸出

10000000000000001000000000000000 
10000000000000001000000000000000 

正如預期的那樣。

$hex = 0x80008000; 

print_r(decbin(~intval($hex)) . '<br/>'); 
print_r(decbin(~$hex)); 

輸出

1111111111111110111111111111111 
1111111111111111111111111111111 

$hex是否定的,爲什麼不切換中間位?

+0

您使用的是什麼版本的PHP?第二種情況適用於我5.3.6 – 2012-03-08 20:13:52

+0

我運行5.3.8並存在問題。 – Pateman 2012-03-08 20:17:13

+0

我正在使用5.2.17 – Vigrond 2012-03-08 20:18:13

回答

0

要在這裏給我自己的問題一槍。

是的這是一個32位/ 64位的差異。

在32位系統中,浮點類型必須佔用兩個內存空間才能獲得所需的64位。 Php使用雙精度(請參閱http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers

$ hex計算爲浮點類型。 Intval和Decbin函數將其轉換爲int類型(上面的第一個示例)

在第二個示例中,我們使用的不是按位運算符,而是在使用decbin之前。這首先翻轉雙存儲空間雙精度浮點數的位,然後轉換爲int秒。給予我們與我們預期不同的東西。

事實上,如果我們把否定內INTVAL的()像這樣:

$hex = 0x80008000; 

print_r(decbin(intval(~$hex)) . '<br/>'); 
print_r(decbin(~$hex)); 

我們得到

1111111111111111111111111111111 
1111111111111111111111111111111 

作爲輸出。

我不夠好,用數學來證明這一點(這可以通過這篇文章http://en.wikipedia.org/wiki/Double_precision的幫助來解決)。但是,也許當我有時間後 -

我認爲這是非常重要的,瞭解如何在計算機中表示數字,以便我們可以瞭解這種異常,而不是稱之爲錯誤。

-1

可能根據本範圍之情形:

從PHP位運算符頁http://us3.php.net/manual/en/language.operators.bitwise.php

未或補運算符(〜)和負二進制數可以 是混亂。

〜2 = -3,因爲您使用公式〜X = -x - 1的十進制數的按位補 是數量的否定減1

注意:只使用4個比特此處下面的例子,但實際上PHP 使用32位。 (即:3 = 0011)2)翻轉位(例如:3 = 0011)2)翻轉一個負數的十進制數(即:-3)轉換爲二進制文件3 步驟:1)將正數版本的十進制數轉換爲 二進制數0011變爲1100)3)add 1(即:1100 + 0001 = 1101)

您可能想知道1101 = -3。那麼PHP使用方法 「2的補碼」來呈現負二進制數。如果最左邊的 位是1,那麼二進制數是負數,並且您翻轉位 並添加1.如果它是0,那麼它是肯定的,並且您不必做任何事情 。所以0010將是正數2.如果它是1101,則它是負數 ,並且您翻轉這些比特以得到0010.加1並且得到0011,這等於 -3。

+0

我不認爲這與問題有關。根據我的理解,'intval($ hex)'應該完全等於'$ hex',所以我期望'〜intval($ hex)===〜$ hex'。 – 2012-03-08 20:27:08

+0

是的,我沒有在這裏轉換任何東西,只是以二進制格式表示數字。 – Vigrond 2012-03-08 20:28:49