in reply to Decoding binary information

Hi njcodewarrior,

Why not use hex?

The first time I encountered it, it seemed like a bit of a misnomer; it actually interprets the given value as a hexadecimal integer, and converts it to decimal (not the reverse, as one might suppose).

For example:

use strict; use warnings; my @values = ( "05F9AD", "F4EC9E", "0005" ); foreach my $value (@values) { my $decval = hex($value); printf "Hex value 0x%08lx = %ld (decimal)\n", $decval, $decval; }

which gives the following results:

Hex value 0x0005f9ad = 391597 (decimal) Hex value 0x00f4ec9e = 16051358 (decimal) Hex value 0x00000005 = 5 (decimal)

s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: Decoding binary information
by njcodewarrior (Pilgrim) on Feb 10, 2007 at 17:49 UTC

    Thanks liverpole.

    The first and third integers are properly converted using hex as you suggested. However, the second number is actually a negative number:

    F4EC9E = -725850

    Any ideas on why?

    Thank you very much for your help. You've already cleared up lots!

    njcodewarrior

      You should sign-extend it, Perl isn't used to working with 24 bit integers.

      Perl can handle 32 bit integers just fine. You could append '00', pack it into a 4 byte structure (a long), and unpack it as a signed long; and finally divide by 256, for the 2 extra zeros you added.

      print unpack('l', pack 'L', hex 'F4EC9E00')/256;
      Or, maybe easier, subtract 2**24 if you see it's 2**23 or more.
      $n = hex 'F4EC9E'; if($n >= 2**23) { $n -= 2**24 } print $n;
      What version of Perl do you have, and what code exactly are you running?

      I could see where F4EC9E might be interpreted as a negative value, since the highest order bit is set.  What I don't understand is why it would evaluate as -725850, which should be represented by F4ECA6:
      use strict; use warnings; my $value; $value = -725850; printf "Hex value 0x%08lX = %ld (decimal)\n", $value, $value; $value = -725858; printf "Hex value 0x%08lX = %ld (decimal)\n", $value, $value __END__ # Output: Hex value 0xFFF4ECA6 = -725850 (decimal) Hex value 0xFFF4EC9E = -725858 (decimal)

      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

        I'm running:

        This is perl, v5.8.5 built for x86_64-linux-thread-multi

        The translation program I'm running was written in C and is only compiled for win32. I'd be more than happy to post it along with the sample hex message if you want to look at it.

        So my reasons for looking further into this are 2-fold: 1) Port it to *nix as this is my native operating environment as well as to be able to run it on as a cronjob and 2) learning about data types and how they are represented on the machine.

        njcodewarrior