2010-08-31 29 views
5

tengo números enteros que flota entre los valores: 4000000000 hasta 4294967000 (que es menos de int máximo para un entero sin signo de 4 bytes)gran número entero de 4 bytes como sin firmar, binario

y quiero guardarla en un archivo , y luego el valor

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

es importante que en el expediente, el valor debe ser exactamente 4 bytes entero sin signo, ya que los dispositivos externos esperan que ese formato de los datos re-leer. Pero PHP almacena esos grandes valores como float y destruye la representación binaria.

¿Cómo puedo escribir esos números en un archivo en ese formato?

[EDIT] THX @FractalizeR esto funciona tengo:

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; 
    } 
} 

pero yo no entiendo muy bien, ¿por qué tengo a -1 en el valor de regresar, y es este binario será producido correcta ?

Respuesta

1

Bueno, divide ese número 4 bytes en 2 números de 2 bytes (entero dividir por 256 * 256 para obtener la primera palabra y restar ese valor de un original para obtener el segundo) y escribe en dos paquetes.

+0

Hey, thx :) ¿Se puede comprobar si mi aplicación está funcionando correctamente? – canni

1

Si desea dividir sus int hasta en 4 bytes que puede hacer lo siguiente:

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

El método utilizado aquí se llama operaciones bit a bit.

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

Espero que esto ayudó.

EDIT:

Creo que así es como se haría lo mismo en PHP:

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

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

+0

Esto no es exactamente PHP :) –

1

No se preocupe acerca de que sea un flotador. Si es entre 2^31 y 2^32-1, no tendrá ningún problema.

Los flotantes PHP tienen una mantisa de 52 bits y, por lo tanto, pueden almacenar sin pérdida de precisión números de 32 bits.

Usted dice pack para codificar un número entero y le pasa un flotador, convertirá el flotador en un número entero.Los flotadores cuyo valor es un número entero entre 2^31 y 2^32-1, se convierten a números negativos en las máquinas de 32 bits:

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

En una máquina de 64 bits, se obtiene un número entero demasiado:

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

Pero su representación de bytes es exactamente la misma. pack devolverá el mismo en ambos:

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