Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Converting negative number to binary with specific width

by pjkang7 (Novice)
on Nov 03, 2015 at 00:07 UTC ( [id://1146779]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, this is my first question post on PerlMonk. Just fyi, I have searched and tried for some good amount of time (>40min) and decided I could not find out what's wrong with my code. It's a simple one.

Basically, I am trying to convert negative number into specific length (10) binary. And it's simply refusing to do that. Here's the code:

my $neg = -1; my $negBin = sprintf ("010.10b", $neg); print $negBin; #returns a lot of 1s instead of 11_1111_1111. (without +underscores)

Another problem i had was if I am trying to convert 1024 into binary number:

my $num = 1024; my $bin = sprintf ("010.10b", $num); print $bin; #returns 100_0000_0000 instead of 00_0000_0000

Apparently, there's something wrong with my sprintf formating....and I can't figure it out. I have used substr to simply cut the string to my desired length as a way around it but I am still interested to find out what I did wrong... I turn to the wisdom of PerlMonks out there. Thank you.

Replies are listed 'Best First'.
Re: Converting negative number to binary with specific width
by BrowserUk (Patriarch) on Nov 03, 2015 at 01:03 UTC

    YOu're using the wring tool. pack & unpack are designed for this:

    print unpack 'b10', pack 's', -1;; 1111111111 print unpack 'b10', pack 's', -21;; 1101011111 print unpack 'b10', pack 's', 1024;; 0000000000

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
    div class=

      I was thinking something more along the lines of

      c:\@Work\Perl\monks>perl -wMstrict -le "for my $n (-2, -1, 0, 1, 2, 1023, 1024, 1025) { my $bin = reverse unpack 'b10', pack 'v', $n; print qq{'$bin' <= $n}; } " '1111111110' <= -2 '1111111111' <= -1 '0000000000' <= 0 '0000000001' <= 1 '0000000010' <= 2 '1111111111' <= 1023 '0000000000' <= 1024 '0000000001' <= 1025
      to get closer to the  'b' formatting of sprintf (although I'm not sure this is any better than substr-inging it). (Update: Also see perlpacktut.)


      Give a man a fish:  <%-{-{-{-<

        what os the is use of pack 'v' for?

      Yup I will definitely use pack unpack next time. I saw that before but I thought I should not have any problem with sprintf. I did manage to work my way through using substr but I do think pack unpack would work nicer. Thanks

        Make sure you look at AnomalousMonk's version of the code.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Converting negative number to binary with specific width
by RichardK (Parson) on Nov 03, 2015 at 00:45 UTC

    The problem is that the b format is for unsigned integers only, so your -1 gets turned into an unsigned int and printing that overflows your field width, giving you lots of ones.The help for sprintf says :-

    %b an unsigned integer, in binary

    BTW sprintf always prints the entire number even if it's bigger than the field width, so this is never going to work for 10 bit binary.

      Thanks, I simply did want -1 to show up as 1111111111... of width 10. which, in unsigned int, it would mean infinite (hence lots of ones...) but I just wanted to cut it at ten 1s.

      I did not know sprintf always print the entire number. Thanks.

Re: Converting negative number to binary with specific width
by Anonymous Monk on Nov 03, 2015 at 14:58 UTC

    I prefer bit-bashing to string-bashing. Whatever floats your boat.

    printf '%0*b', $bits, $num & ((1<<$bits)-1)

      If you insist on strings, substr is still probably easier than pack.

      substr(sprintf("%0*b", $bits, $num), -$bits)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1146779]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2024-04-23 18:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found