2010-08-31 18 views
5

mam całkowitymi która płynie pomiędzy wartościami: 4000000000-4294967000 (co jest mniej niż int max dla 4 bajtów unsigned int)Napisz duży 4 bajtów jako liczbę całkowitą bez znaku, binarny

i chcę zapisać go do pliku , a następnie ponownie odczytać wartość

$f = fopen($fileName, 'wb'); fwrite($f, pack('I', $value)); 

istotne jest to, że w pliku, wartość musi być dokładna 4 bajt unsigned int, ponieważ urządzenia zewnętrzne będą oczekiwać, że format danych. Ale PHP przechowuje te duże wartości jako float i niszczy binarną reprezentację.

Jak mogę zapisać te liczby do pliku w tym formacie?

[EDIT] @FractalizeR thx działa to mam:

protected static function handleUint($direction, $value) 
{ 
    if($direction == 'encode') 
    { 
     $first2bytes = intval($value/(256 * 256)); 
     $second2bytes = intval($value - $first2bytes); 

     return pack('n2', $first2bytes, $second2bytes); 
    } 
    else 
    { 
     $arr = unpack('n2ints', $value); 
     $value = $arr['ints1'] * (256 * 256) + intval($arr['ints2']) - 1; 
     return $value; 
    } 
} 

ale dont bardzo rozumiem, dlaczego muszę -1 wartości powracającego, i jest to binarny zostanie wyprodukowany poprawne ?

Odpowiedz

1

Well, podzielony, że liczba 4 bajty na 2 2-bajtów liczb (liczba całkowita dzielenie przez 256 * 256, aby uzyskać pierwsze słowo i odjąć tę wartość od pierwotnego, aby uzyskać drugi) i pisz w dwóch paczkach.

+0

Hej, thx :) Można sprawdzić, czy moja implementacja pracuje prawidłowe? – canni

1

Jeśli chcesz podzielić int na 4 bajty można wykonać następujące czynności:

int x = 13434; 
byte[] buff = new byte[] { 
     (byte)((x >> 24) & 0xff), 
     (byte)((x >> 16) & 0xff), 
     (byte)((x >> 8) & 0xff), 
     (byte((x) & 0xff) 
} 

Metoda stosowana tutaj nazywa operacje bitowe.

Patrz: http://en.wikipedia.org/wiki/Bitwise_operation

Nadzieja to pomogło.

EDIT:

Myślę, że to w jaki sposób zrobić to samo w PHP:

$arr = array(
     ((x >> 24) & 0xff), 
     ((x >> 16) & 0xff), 
     ((x >> 8) & 0xff), 
     (x & 0xff) 
); 

Patrz: http://php.net/manual/en/language.operators.bitwise.php

+0

To nie jest całkiem PHP :) –

1

nie martw się o to czy jest pływak. Jeśli jest między 2^31 i 2^32-1, nie będziesz miał żadnych problemów.

Pływaki PHP mają 52-bitową mantysę, dzięki czemu można przechowywać bez utraty precyzji liczby 32-bitowe.

Poinformujesz: pack o zakodowaniu liczby całkowitej i przekazujesz jej wartość zmiennoprzecinkową, przekształci ona liczbę zmiennoprzecinkową w liczbę całkowitą.Pływaki, którego wartość jest liczbą całkowitą z przedziału 2^31 a 2^32-1, zamieniony na liczbach ujemnych na maszynach 32-bitowych:

 
$ php -r "var_dump((int) 4000000000);" 
int(-294967296) 

Na komputerze 64-bitowym, masz całkowitą też:

 
$ php -r "var_dump((int) 4000000000);" 
int(4000000000) 

Ale ich reprezentacja bajtów jest dokładnie taka sama. pack powróci takie same na obu:

 
$ php -r "var_dump(unpack('H*', pack('I', (float) 4000000000)));" 
array(1) { 
    [1]=> 
    string(8) "00286bee" 
} 
Powiązane problemy