Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:


Hi

I've been trying to convert decimal integers into binary
and was using the following code

By dempa on May 31, 2000
print dec2bin(13) . "\n"; sub dec2bin { return (sprintf "%b",shift); }
By repson
sub to_bin { my $num = shift; my $ret = ''; while ($num){ $ret = (($num % 2) ? 1 : 0); $num >>= 1; } }
but they don't work for numbers > 32 bits, is there an easy way to do this?

Replies are listed 'Best First'.
Re (tilly) 1: dec to bin conversion for large numbers
by tilly (Archbishop) on Sep 14, 2001 at 18:29 UTC
(tye)Re: dec to bin conversion for large numbers
by tye (Sage) on Sep 14, 2001 at 21:21 UTC

    Asuming IEEE double-precision floating-point numbers on your platform, you can use this horrid idea (:

    BEGIN { my $code= ""; if( pack("L",1) ne pack("N",1) ) { $code= "''.reverse "; } eval "sub to_big_endian { ${code}pop }; 1" or die $@; } sub to_bin { my( $num )= @_; my( $sign, $exp, $mant )= unpack "A1A11A*", unpack "B*", to_big_endian pack"d",2*$num+1; $mant =~ s/10*$//; return "1".$mant; }
    That should work to about 52 bits for positive integers on compatible platforms.

    Don't put this in production code! :)

            - tye (but my friends call me "Tye")
Re: dec to bin conversion for large numbers
by I0 (Priest) on Sep 15, 2001 at 12:26 UTC
    use Math::BigInt; sub dec2bin{ my $i = new Math::BigInt shift; $i&&dec2bin($i/65536).sprintf"%016b",$i%65536; } print dec2bin('123 456 789 123 456 789');
Re: dec to bin conversion for large numbers
by claree0 (Hermit) on Sep 14, 2001 at 17:55 UTC
    have a look at pack and unpack
      If you have an example, I would be interested in seeing it. I've been playing around with How do I convert between decimal and binary? to help this person but keep running into the 32-bit limitation also. I tried modifying the example by vroom to no avail. Note that where vroom used "B32" I changed it to "B64". There may be a way to finesse it into working but I haven't lucked into it yet.
      print dec2bin(2**31); sub dec2bin { my $str = unpack("B64", pack("N", shift)); $str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros return $str; }
      This correctly produces
      10000000000000000000000000000000
      But if you use anything larger than 2**31, you get
      11111111111111111111111111111111
      @a=split??,'just lose the ego and get involved!';
      for(split??,'afqtw{|~'){print $a[ord($_)-97]}
Re: dec to bin conversion for large numbers
by derby (Abbot) on Sep 15, 2001 at 05:15 UTC
    AM,

    Not very portable but some fun with Inline on I386 Linux:

    #!/usr/local/bin/perl use Inline C; print dec2bin(13) . "\n"; print idec2bin(8589934593) . "\n"; sub dec2bin { return ( sprintf "%b", shift ); } __END__ __C__ void idec2bin ( SV *num ) { long long count; long long MASK; long long var; char *beg; char *end; count = sizeof( var ) * 8; MASK = 1LL << (count-1); beg = SvPV( num, PL_na ); var = strtoll( beg, &end, 10 ); while( count-- ) { printf( "%d", (var & MASK) ? 1 : 0 ); var <<= 1; } }
    -derby
Re: dec to bin conversion for large numbers
by chiller (Scribe) on Sep 14, 2001 at 21:42 UTC
    How about a little DIY?

    This is untested, but...

    use POSIX qw(floor); sub dec2Bin($) { $n = shift; while ($n != 0) { $k = $n % 2; $n = floor($n / 2); $b = $k . $b; } print "$b"; }
    chiller
      yeah that doesn't work...

      So I have a more general question:

      Anything >= 2^11 (or so) results in perl printing "inf"? Is there a way to force a "long" primitive, or what?