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

I'm trying to make a Perl script to generate a test file for my 8 bit signed multiplier. Thus, I need to generate 8bit signed numbers in 2's complement form.
  • Comment on How do I convert from decimal to 2's Complement

Replies are listed 'Best First'.
Re: How do I convert from decimal to 2's Complement
by I0 (Priest) on Apr 08, 2002 at 06:14 UTC
    sub dec_bin2s { return unpack "B8", pack "c", shift; }
      This one is correct (as I'm sure I0 knows).

      From perldoc -f pack:

      c   A signed char value.
      ...
      i   A signed integer value.
          (This 'integer' is at least 32 bits wide.  Its exact
          size depends on what a local C compiler calls 'int',
          and may even be larger than the 'long' described in
          the next item.)
      
      The question asks specifically for signed 8-bit, which is "c", a signed char value (8 bits). "At least 32 bits" is not 8 bits.
Re: How do I convert from decimal to 2's Complement
by tachyon (Chancellor) on Apr 08, 2002 at 05:41 UTC
    print "$_\t", dec_bin2s($_), "\n" for -42 .. 42; sub dec_bin2s { $dec = shift; return unpack "B8", (pack "i", $dec); }
•Re: How do I convert from decimal to 2's Complement
by merlyn (Sage) on Apr 08, 2002 at 16:27 UTC
    Those aren't "decimal" to 2's complement. They're "number represented as 2s complement". Perl numbers aren't in "decimal" internally.
Re: How do I convert from decimal to 2's Complement
by Anonymous Monk on Aug 30, 2020 at 15:46 UTC
    #!/usr/bin/perl my $decimal=-33; #How to generate: #$decimal - your Perl variable. MUST be: -127<$decimal<127 my $packed=pack("N",$decimal); # Little-endian 4 byte. my $YOUR8BITVALUE=substr($packed,-1); # last byte from $packed open F,">your_test_file"; print F $YOUR8BITVALUE; close F; # Now you have file with your $decimal # as one byte in "two's complement"; # How to get from file: open F, "<your_test_file"; read(F,$packed,1); #read byte; my $value; # result if (unpack("N","\x00\x00\x00".$packed) & (1<<7)) { # sign bit is set. It's negative value $packed=("\xFF\xFF\xFF").$packed; # expand to int with 3 byte of 0xF +F $value=-(unpack("N",~$packed)+1); # inverse all bits and unpack,incr +ement,reverse sign. } else { $packed=("\x00\x00\x00").$packed; # expand to int $value=unpack("N",$packed); unpack } print "$value\n"; # That's all!