Binary to Decimal for >2**32

Discussion in 'Perl Misc' started by Graham Drabble, Nov 14, 2007.

  1. Hi all,

    I have been using a binary to decimal converter for number <2**16 for
    a while now using

    $bin = sprintf("%016b",$dec)

    which works fine.

    I've now had to try and do the same conversion for numbers up to 2**
    48 and have discovered that this does not work for numbers >=2**32
    (everything >=2**32 returns the same as (2**32)-1 ).

    I'm currently getting round this with

    use strict;
    use warnings;
    use Math::BigInt;

    my $num = new Math::BigInt 2**47 + 2**31 + 2**30;
    if ($num >= 2**32){
    my $upper = int($num / (2**32));
    my $lower = $num % 2**32;

    $upper = sprintf ("%016b",$upper);
    $lower = sprintf ("%032b",$lower);
    print "$upper$lower\n";
    }
    else
    {
    printf ("%048b\n",$num);
    }

    Which works but seems very inelegant. Does anyone have a better
    suggestion?

    Also hex() returns a warning when given a hex string >2**32 but
    returns the correct result. Is this something that can be relied on
    or do I need to find a work around for that as well?

    --
    Graham Drabble
    http://www.drabble.me.uk/
    Graham Drabble, Nov 14, 2007
    #1
    1. Advertising

  2. Graham Drabble wrote:
    > I have been using a binary to decimal converter for number <2**16 for
    > a while now [...] which works fine.
    > I've now had to try and do the same conversion for numbers up to 2**
    > 48 and have discovered that this does not work for numbers >=2**32


    > use Math::BigInt;

    [...]
    > Which works but seems very inelegant. Does anyone have a better
    > suggestion?


    Use a perl that is compiled with 64-bit support on a 64-bit machine.

    jue
    Jürgen Exner, Nov 14, 2007
    #2
    1. Advertising

  3. Graham Drabble

    Ben Morrow Guest

    Quoth "Jürgen Exner" <>:
    > Graham Drabble wrote:
    > > I have been using a binary to decimal converter for number <2**16 for
    > > a while now [...] which works fine.
    > > I've now had to try and do the same conversion for numbers up to 2**
    > > 48 and have discovered that this does not work for numbers >=2**32

    >
    > > use Math::BigInt;

    > [...]
    > > Which works but seems very inelegant. Does anyone have a better
    > > suggestion?

    >
    > Use a perl that is compiled with 64-bit support on a 64-bit machine.


    s/ on a 64-bit machine//;

    ~% perl -v

    This is perl, v5.8.8 built for i386-freebsd-64int
    <snip>

    ~% perl -le'print sprintf "%048b", 2**37'
    000000000010000000000000000000000000000000000000

    Ben
    Ben Morrow, Nov 15, 2007
    #3
  4. Graham Drabble

    Mumia W. Guest

    On 11/14/2007 02:45 PM, Graham Drabble wrote:
    > Hi all,
    >
    > I have been using a binary to decimal converter for number <2**16 for
    > a while now using
    >
    > $bin = sprintf("%016b",$dec)
    >
    > which works fine.
    >
    > I've now had to try and do the same conversion for numbers up to 2**
    > 48 and have discovered that this does not work for numbers >=2**32
    > (everything >=2**32 returns the same as (2**32)-1 ).
    >
    > I'm currently getting round this with
    >
    > use strict;
    > use warnings;
    > use Math::BigInt;
    >
    > my $num = new Math::BigInt 2**47 + 2**31 + 2**30;
    > if ($num >= 2**32){
    > my $upper = int($num / (2**32));
    > my $lower = $num % 2**32;
    >
    > $upper = sprintf ("%016b",$upper);
    > $lower = sprintf ("%032b",$lower);
    > print "$upper$lower\n";
    > }
    > else
    > {
    > printf ("%048b\n",$num);
    > }
    >
    > Which works but seems very inelegant. Does anyone have a better
    > suggestion?
    >
    > Also hex() returns a warning when given a hex string >2**32 but
    > returns the correct result. Is this something that can be relied on
    > or do I need to find a work around for that as well?
    >


    Use the 'as_bin' method, e.g.:

    my $num = new Math::BigInt 2**47 + 2**31 + 2**30;
    print $num->as_bin, "\n";

    The output will be prefixed with "0b" which you can remove.
    Mumia W., Nov 15, 2007
    #4
  5. Graham Drabble

    Mumia W. Guest

    On 11/15/2007 10:40 AM, Graham Drabble wrote:
    > [...]
    > Anyone got any advice regarding a substitute for hex()? Whilst it works
    > on all the environments I see I don't like to rely on something working
    > when the docs say it won't and the error message will worry users.
    > Unfortunately using 64bit Perl isn't an option.
    >


    my $num2 = Math::BigInt->new('0x8000c0000000');
    print $num2, "\n";

    :)

    I hope I made your day a little brighter.
    Mumia W., Nov 15, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ven
    Replies:
    3
    Views:
    1,322
  2. Gilbert Fine
    Replies:
    8
    Views:
    897
    Zentrader
    Aug 1, 2007
  3. Vitaliy
    Replies:
    1
    Views:
    473
    Peter Otten
    May 29, 2008
  4. valpa
    Replies:
    11
    Views:
    1,512
    Steven D'Aprano
    Mar 24, 2009
  5. Replies:
    0
    Views:
    287
Loading...

Share This Page