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

I am trying to convert from decimal to a binary. I have written this thus far and it keeps returning 0. why would it do that. I am trying to get it to concatenate the numbers and then return the value.
#!/usr/bin/perl -w use strict; use Term::ReadKey; my ($inNumber,$signedMag,$bias127,$onesComp,$twosComp); print "Enter an 8-bit decimal integer: "; $inNumber = ReadLine 0; chomp $inNumber; ReadMode 'normal'; print "\n"; if ($inNumber =~ /^[+-]?\d+$/) { print $inNumber ; print "\n"; }else{ warn "not an integer"; } if ($inNumber > 127 || $inNumber < -127) { warn "number is not 8 bit"; exit; } $signedMag = dec2bin($inNumber); print $signedMag; print "\n"; sub dec2bin { my $binnumb; my $binary = $inNumber % 2; $inNumber = int($inNumber / 2); $binnumb = $binnumb . $binary; if($inNumber > 0) {dec2bin($inNumber);} return $binnumb; }

Replies are listed 'Best First'.
Re: Why does it return 0?
by Ovid (Cardinal) on Feb 05, 2004 at 01:54 UTC

    From the Perl Cookbook:

    sub dec2bin { my $str = unpack("B32", pack("N", shift)); $str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros return $str; } sub bin2dec { return unpack("N", pack("B32", substr("0" x 32 . shift, -32))); }

    And your code is always returning zero because you declare $binnumb inside of the subroutine, thus resetting it every time it is called. At the last execution of the routine, $inNumb % 2 is zero.

    Cheers,
    Ovid

    New address of my CGI Course.

      Thank you Ovid, I was actually going to use this but I have to actually do it manually.
        If you want to know how conversion of numbers to a string works, try this:
        $num = 1234567; $result = ""; $base = 2; do { use integer; my $digit = $num % $base; substr($result, 0, 0) = $digit; # for any number < 10 $num /= $base; } while $num; print $result;
        If you like fixed width output, add enough zeros to the front, afterwards:
        substr($result, 0, 0) = "0" while length($result) < 32;

        If you want to play with $base > 10, for example hexadecimal , try:

        $num = 1234567; $base = 16; $result = ""; my @digit = (0 .. 9, 'A' .. 'Z'); do { use integer; my $digit = $num % $base; substr($result, 0, 0) = $digit[$digit]; # for base up to 36 $num /= $base; } while $num; print $result;

        Note that the do { ... } while $num; construct makes the loop execute at least once, so you get a proper result for zero.

Re: Why does it return 0?
by ysth (Canon) on Feb 05, 2004 at 02:07 UTC
    sub dec2bin { my $inNumber = shift; my $sign = $inNumber=~s/^-// ? '-' : ''; return $sign.sprintf "%b", $inNumber; }
    is how I'd do it (untested). (The "%b" format was added in perl 5.6.0.) Don't forget to actually use the parameter you pass. Also, in your code $binnumb = $binnumb . $binary would be usually written $binnumb .= $binary. (Either is exempt from the usual warning that $binnumb is undefined; other operators special-cased this way are +, -, ||, &&, ^, |, ++, --.)
      I tried to use the $binnumb .= $binary but it doesn't seem to be concatenating the string it just returns the last value of $binary.
        In your original code, you needed to have had a loop, doing the % and / and append until the number is zero. But you're better off just using sprintf "%b" or unpack.

        Update: except that you'd have to do $binnumb = $binary . $binnumb instead, which will get a warning unless you initialize $binnumb to '' at the start. And you need to handle negative numbers.