http://qs1969.pair.com?node_id=678654

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

I have a file that contains frequencies stored in a 3 byte format and I am trying to convert them from hex to decimal.

From a representation viewpoint these byte formats equal these numbers:

0x3CB415 = 888.997500 0x007102 = 100.000000 0x00350C = 500.000000 0x006A18 = 1000.000000 0x300515 = 860.99000 0x80A903 = 150.000000 0xC05E04 = 179.00000
I have tried pack and unpack but no luck. I think this format is little endian format since other numbers such as counters 0x0300 is actually 3.

my $t1 = 0xC05E04; my $t2 = unpack('f', $t1);

Anyway, I do not have any ideas how to do this conversion. I would appreciate any guidance you would provide.

Thanks Mike

Replies are listed 'Best First'.
Re: Convert binary to decimal problem
by ikegami (Patriarch) on Apr 06, 2008 at 16:41 UTC

    0x007102 = 100.000000 0x00350C = 500.000000

    0x0C3500 = 0x027100 * 5, so the byte order is reversed.

    0x027100 = 160000, so maybe packed = 1600 * unpacked?

    0x300515 / 1600 =? 860.99 Yes!

    Solution:

    my $raw = 0x300515; my $val = unpack('N', "\x00".pack('V', $raw))/1600
    or
    my $raw = "\x30\x05\x15"; my $val = unpack('V', "$raw\x00")/1600;
Re: Convert binary to decimal problem
by hawtin (Prior) on Apr 07, 2008 at 13:01 UTC

    The first thing to say is that you are probably converting to a floating point format, rather than a decimal one. The next thing to notice is that your numbers are 24 bits long, this is not the normal way that modern floating point numbers are encoded they tend to be 32 bit (for example see Wikipedia). From memory I think there was an IBM 24 bit float format from the 1970s.

    As you say the bigendian/littleendian split is worth looking at, also sometime these things are written backwards as well (giving 4 combinations of bit order).

    The approach I would take is to get as many examples as you can, see if you can encode numbers that are related to each other, for example 1.25, 2.5, 5, 10, 20 and 40. Also select "simple" numbers, like 0.0, 1.0, -1.0 etc and simple relationships, for example compare 0.5, 1.0 and 1.5. Then rewrite every one in binary and see what the patterns are. If you look at the numbers you gave:

    0b00111100 10110100 00010101 = 888.997500 0b00000000 01110001 00000010 = 100.000000 0b00000000 00110101 00001100 = 500.000000 0b00000000 01101010 00011000 = 1000.000000 0x00110000 00000101 00010101 = 860.99000 0x10000000 10101001 00000011 = 150.000000 0x11000000 01011110 00000100 = 179.00000

    There are obviously too few numbers here to see the pattern but I do notice that 500 and 1000 have an obvious relationship.

    Once I understand the conversion I would then use pack (especially with "b") to unpick the parts (for a float that would be the sign, mantissa and exponent and don't forget any implied MSB).

Re: Convert binary to decimal problem
by Joost (Canon) on Apr 06, 2008 at 16:38 UTC