2014-01-24 40 views
0

我需要做一些工作來抽出一些我從其他來源獲得的數據。右移不能按預期的方式工作

我已經得到的數據是這樣的二進制:

01100011 00000000 00000000 00000000 

這是十進制數99

我要屏蔽(按位與)的小端編碼它與此值:

01000000 00000000 00000000 00000000 

然後一路轉移到右邊(30位)。

當我嘗試右移它,但是,我得到:

00000000 00000000 00000000 00110000 

而且我想不通爲什麼。

下面的代碼:

function binrep($bin,$len=32) { 
    return implode(' ',str_split(str_pad(decbin(hexdec(bin2hex($bin))),$len,'0',STR_PAD_LEFT),8)); 
} 


function mask($data,$pos,$len=1,$size=32) { 
    $bits = (1<<$len)-1; 
    $shift = $size - $pos - $len; 
    $mask = pack('N',$bits << $shift); 
    echo binrep($data)."\n".binrep($mask)."\n".binrep(($data&$mask)>>$shift); 
    return ($data & $mask) >> $shift; 
} 

mask(pack('V',99),1); 

剛纔那個價值來自何處?爲什麼不是結果

00000000 00000000 00000000 00000001 

+0

打印變量的值(!$位)和你會看到的。 –

+0

@ KarolyHorvath:咦?如何以非二進制格式打印它們來幫助我? '$ data&$ mask'是'@',右移時是'0',它告訴我PHP可能只是解釋第一個字節。我不明白這有助於回答我的問題。 '$ bits'是'1',這正是我所期望的。 – mpen

+0

@ h2ooooooo:可以......我認爲它只是不喜歡右移多字節值。 – mpen

回答

1

這是一種類型不匹配。由於($data & $mask)的計算結果爲字符串,因此php會隱式地將$shift的類型更改爲字符串以執行操作。根據php文檔,這意味着>>運算符正在使用ascii值來進行計算。我添加了這個功能,你的代碼:

function decrep($bin) 
{ 
return hexdec(bin2hex($bin)); 
} 

然後做轉向使用此功能binrep(pack('N',((decrep($data) & decrep($mask)) >> $shift)))的權利,並給出正確的結果。

+0

看起來像那些作品。謝謝 ! – mpen

0

對任何人的完整的解決方案,需要從32位int拔出隨機位:

function decrep($bin) { 
    return hexdec(bin2hex($bin)); 
} 

function binrep($bin,$len=32) { 
    return implode(' ',str_split(str_pad(decbin(hexdec(bin2hex($bin))),$len,'0',STR_PAD_LEFT),8)); 
} 

function extractBits($data,$pos,$len=1,$size=32) { 
    $bits = (1<<$len)-1; 
    $shift = $size - $pos - $len; 
    $mask = pack('N',$bits << $shift); 
    return (decrep($data) & decrep($mask)) >> $shift; 
} 

用法:

$result = extractBits($data,1,2); // pulls out the 2nd and 3rd to left bit, returns number in range 0-3