2009-01-27 9 views

Répondre

23
sub bin2dec { 
    return unpack("N", pack("B32", substr("0" x 32 . shift, -32))); 
} 
+3

Chaque outil que je demande me dit que 111111111111111111111111111111111 se traduit 8589934591. Juste comment sont-vous que 42949672958589934591 est correct? – innaM

+2

Ceci est fait par le built-in oct() aussi, bien que ce soit un nom assez pauvre pour cela. –

56

Ma façon préférée est:

$x_num = oct("0b" . $x_bin); 

Je cite man perlfunc:

 
    oct EXPR 
    oct  Interprets EXPR as an octal string and returns the 
      corresponding value. (If EXPR happens to start 
      off with "0x", interprets it as a hex string. If 
      EXPR starts off with "0b", it is interpreted as a 
      binary string. Leading whitespace is ignored in 
      all three cases.) 
+1

C'est ... choquant. Je vous remercie. – innaM

+0

@edg: c'est à prévoir sur une plateforme 32 bits; fonctionne pour moi avec 64 bits, mais avec un avertissement de portabilité. – ysth

+2

J'ai toujours utilisé le pack, mais j'ai juste benchmarké pack, oct, et Bit :: Vector et c'est de loin le plus rapide des trois. Il est 1449% plus rapide que Bit :: Vector et 316% plus rapide que pack sur mon système. – gpojd

12

Comme d'habitude, il y a aussi un excellent module de CPAN qui devrait être mentionné ici: Bit::Vector .

La transformation ressemblerait à quelque chose comme ceci:

use Bit::Vector; 

my $v = Bit::Vector->new_Bin(32, '0001001100101'); 
print "hex: ", $v->to_Hex(), "\n"; 
print "dec: ", $v->to_Dec(), "\n"; 

Les chaînes binaires peuvent être de presque toute la longueur et vous pouvez faire d'autres choses comme peu propre décalage, etc.

6

En fait, vous pouvez juste coller '0b' sur le devant et il est traité comme un nombre binaire.

perl -le 'print 0b101' 
5 

Mais cela ne fonctionne que pour un seul mot.

0

Vous pouvez utiliser la méthode eval() pour contourner la restriction simple mot:

eval "\$num=0b$str;";