2010-07-16 10 views
4

Pourquoi obtenir la sortie suivante sur une architecture x64? Il semble qu'il puisse gérer les octets 64 bits signés, mais il ne peut pas les emballer/les déballer. Selon la documentation, http://us3.php.net/pack, la taille de I devrait être dépendant de la machine, ce qui dans ce cas est de 64 bits.Pack/décompresser un int 64 bits sur une architecture 64 bits en PHP

$ php -r 'echo PHP_INT_MAX;' 
9223372036854775807 

$ php -v 
PHP 5.2.9 (cli) (built: Apr 17 2009 03:29:14) 
Copyright (c) 1997-2009 The PHP Group 
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies 
+0

Que 'écho PHP_INT_MAX;' te donner? – Wrikken

+0

Quelle version de PHP utilisez-vous? –

+0

@Wrikken et @R. Hill, voir les modifications ci-dessus. – sberry

Répondre

0

pack("I") demande un nombre entier, qui, pour le modèle I32LP64 sur x86_64 est encore généralement 32 bits de large - au moins en C. Les interprètes ajoutent souvent leur propre définition sur le dessus.

0

Il n'existe pas de version 64 bits de PHP 5.2. La première version 64 bits était une version expérimentale de 5.3.0 du côté Windows. Donc, si vous utilisez 5.2.9 sur Windows, vous devrez au moins passer à 5.3.0 pour pouvoir obtenir une version 64 bits.

Si ma prémisse est correcte, et que vous utilisez PHP sous Windows, cela est comme ça ne fonctionne pas ...

Pour vous d'avoir accès au composant 64 bits de votre CPU, votre tapis doit être 64 bits. Cela signifie que le processeur doit prendre en charge 64 bits, le système d'exploitation doit prendre en charge 64 bits et l'application doit prendre en charge 64 bits. Si l'un d'entre eux utilise 32 bits, la pile entière sera de 32 bits à partir de ce point. Il va au plus petit dénominateur commun.

0

Parce que pack prend le deuxième paramètre sous forme de chaîne et le convertit en un entier de 32 bits. Le seul soulagement est non signé en ce qui concerne les limitations de taille de bit. En regardant le code source, je vois bientôt une version 64 bits de Perl qui utilise 'Q' pour forcer la machine endian 64 bits.

2

Voici une fonction pour emballer une valeur entière de toutes les tailles en bits N:

function encode_int($in, $pad_to_bits=64, $little_endian=true) { 
    $in = decbin($in); 
    $in = str_pad($in, $pad_to_bits, '0', STR_PAD_LEFT); 
    $out = ''; 
    for ($i = 0, $len = strlen($in); $i < $len; $i += 8) { 
     $out .= chr(bindec(substr($in,$i,8))); 
    } 
    if($little_endian) $out = strrev($out); 
    return $out; 
} 

Voici une fonction pour décoder les nombres entiers emballés:

function decode_int(&$data, $bits=false) { 
      if ($bits === false) $bits = strlen($data) * 8; 
      if($bits <= 0) return false; 
      switch($bits) { 
        case 8: 
          $return = unpack('C',$data); 
          $return = $return[1]; 
        break; 

        case 16: 
          $return = unpack('v',$data); 
          $return = $return[1]; 
        break; 

        case 24: 
          $return = unpack('ca/ab/cc', $data); 
          $return = $return['a'] + ($return['b'] << 8) + ($return['c'] << 16); 
        break; 

        case 32: 
          $return = unpack('V', $data); 
          $return = $return[1]; 
        break; 

        case 48: 
          $return = unpack('va/vb/vc', $data); 
          $return = $return['a'] + ($return['b'] << 16) + ($return['c'] << 32); 
        break; 

        case 64: 
          $return = unpack('Va/Vb', $data); 
          $return = $return['a'] + ($return['b'] << 32); 
        break; 

      } 
      return $return; 
    } 
Questions connexes