Search code examples
perlpackunpack

perl. convert 64-bit binary number to decimal


I have a string contains 64 binary symbols.

I need to convert it into the decimal number. How can I do it in perl?

sub bin2dec {
    return unpack("N", pack("B64", substr("0" x 64 . shift, -64)));
}

doesn't work. it converts just first 32 bit.


Solution

  • From the docs,

    N  An unsigned long (32-bit) in "network" (big-endian) order.
    

    The 64 bit equivalent would be "Q>".

    q  A signed quad (64-bit) value.
    Q  An unsigned quad value.
      (Quads are available only if your system supports 64-bit
      integer values _and_ if Perl has been compiled to support
      those. Raises an exception otherwise.)
    
    >   sSiIlLqQ   Force big-endian byte-order on the type.
        jJfFdDpP   (The "big end" touches the construct.)
    

    So you could use the following:

    unpack("Q>", pack("B64", substr("0" x 64 . shift, -64)))
    

    That said, the above is needlessly complicated. Whoever coded that was was probably not aware of oct's ability to parse binary numbers because the above can be reduced to

    oct("0b" . shift)
    

    But what do you do if you don't have a 64-bit build of Perl? You need to use some kind of object that overloads math operations. You could use Math::BigInt, but I suspect that won't be nearly as fast as Math::Int64.

    use Math::Int64 qw( string_to_int64 );
    string_to_int64(shift, 2)
    

    For example,

    $ perl -MMath::Int64=string_to_int64 -E'say string_to_int64(shift, 2);' \
       100000000000000000000000000000000
    4294967296