1. 程式人生 > >二進位制資料處理(經緯度)

二進位制資料處理(經緯度)

有一個數字 :(+,-)30.6789

現在要用4個位元組 32位表示

用高位(1位)表示正負(1代表+ 0 代表-)

用10位表示 整數 30

用21位表示小數6789

我想要的結果為 4個16進位制的數

 

 

 

 

//補位數 函式

string str_pad ( string , int pad_length , string pad_string , int pad_type);

string 指定字串,pad_length指定長度,pad_string用來填充的字串(可選引數),pad_type指定填充位置(可選引數,STR_PAD_LEFT,STR_PAD_BOTH);

如果pad_string , pad_type均為空,那麼就等於預設pad_string 為空格, pad_type就是自動填充在指定字串的末端.

 

 

//進位制轉換

1: 十進位制轉二進位制 decbin() 例:echo decbin(12); //輸出 1100

2:十進位制轉八進位制 decoct() 例:echo decoct(15); //輸出 17

3:十進位制轉十六進位制 dechex() 例:echo dechex(10); //輸出 a

4:二進位制轉十六制進 bin2hex() 例:echo bin2hex('A'); //字元對應的ascii 十進位制 65 十六進位制 41 返回 ASCII 字串,為引數 str 的十六進位制表示。轉換使用位元組方式,高四位位元組優先

$binary = "11111001"; $hex = dechex(bindec($binary)); echo $hex;//輸出f9

5:二進位制轉十制進 bindec() 例:echo bindec('110011'); //輸出 51

6:八進位制轉十進位制 octdec() 例:echo octdec('77'); //輸出 63

7:十六進位制轉十進位制 hexdec() 例: var_dump(hexdec("See")); var_dump(hexdec("ee")); // both print "int(238)"

8:任意進位制轉換 base_convert() 例:$hexadecimal = 'A37334'; echo base_convert($hexadecimal, 16, 2);//輸出 101000110111001100110100

 

//PHP 位移運算子(<<左移和>>右移)

<< 位左移 ::左移運算的實質是將對應的資料的二進位制值逐位左移若干位,並在空出的位置上填0,最高位溢位並捨棄

例:$a=10;

$b=$a<<2;

則$b=40,根據手冊描述可以看出位運算可以看出向左移一位,則是實現乘2運算。由於位移操作的運算速度比乘法的 運算速度高很多。因此在處理資料的乘法運算的時,採用位移運算可以獲得較快的速度。

**提示 將所有對2的乘法運算轉換為位移運算,可提高程式的執行效率

 

>> 位右移 ::右移運算的實質是將對應的資料的二進位制值逐位右移若干位,並捨棄出界的數字。如果當前的數為無符號數, 高位補零

例:$a = 25;//11001

b=a>>2;//等價於:11001 >> 01100, 01100 >> 00110.那麼110 =》 6,即25/4 = 6

b=(0000 0000 0000 0110)=6

如果當前的資料為有符號數,在進行右移的時候,根據符號位決定左邊補0還是補1。

如果符號位為0,則左 邊補0;但是如果符號位為1,則根據不同的計算機系統,可能有不同的處理方式。

可以看出位右移運算,可以實現對除數為2的整除運算。

**提示 將所有對2的整除運算轉換為位移運算,可提高程式的執行效率

 

 

// 高位 低位

???????????

 

 

 

//ord chr

string chr (int ascii); 該函式用於將ASCII碼值轉化為字串

int ord(string str); 該函式用於將字串轉化為ASCII碼值

例:

<?php

//使用chr()函式和ord()函式進行字串與ASCII碼之間的轉換,程式程式碼如下:

$str1=chr(88);

echo $str1; //返回值為X

echo "\t";

$str2=ord('S');

echo $str2; //返回值為83

 

//執行結果:X 83

?>

 

 

 

答案::::

 

//根據經緯度 轉換為 二進位制

// 10位代表整數,21位代表小數 用高位(1位)表示正負(1代表+ 0 代表-)

public function LatLngToBin($latLng){

 

$latLngArr = explode('.',$latLng);

$int_bin = decbin($latLngArr[0]);

$int = str_pad($int_bin,10,'0',STR_PAD_LEFT);

$abc = str_pad($latLngArr[1],6,'0',STR_PAD_RIGHT);

$xs_bin = decbin($abc);

$xs = str_pad($xs_bin,21,'0',STR_PAD_LEFT);

$str = '1'.$int.$xs;

$arr = str_split($str,8);

$string = '';

for($i=3;$i>=0;$i--){

$string.= chr(bindec($arr[$i]));

}

return $string;

}

 

 

 

// 解析經緯度

$latRes = $this -> commonfun($str,4,4); //緯度 南緯1 北緯0

$lat = $latRes & 0x7FFFFFFF;

$new_lat = $lat >> 21;

$lat_xs = ($lat & (0x1fffff))/1000000;

$p_lat = $new_lat + $lat_xs;

 

 

/*

* shen

* 2017-5-18

* 為解析二進位制資料服務的方法

* 引數:$str:需要解析的字串 $skip:跳過的位數 $len:需要解析的位數

*/

public function commonfun($str,$skip,$len){

 

$result = 0;

for($i=0;$i<$len;$i++){

$result = (ord($str[$skip+$i]) << ($i << 3)) | ($result);

}

return $result;

}

 

 

/*

* 高效的取1方法

*

* 得到一個十進位制數裡有幾個1

*/

function getBit1($n)

{

$n = ($n&0x55555555) + (($n>>1)&0x55555555);

$n = ($n&0x33333333) + (($n>>2)&0x33333333);

$n = ($n&0x0f0f0f0f) + (($n>>4)&0x0f0f0f0f);

$n = ($n&0x00ff00ff) + (($n>>8)&0x00ff00ff);

$n = ($n&0x0000ffff) + (($n>>16)&0x0000ffff);

return $n;

}