简体   繁体   中英

Perl pack and unpack functions

I am trying to unpack a variable containing a string received from a spectrum analyzer :

#42404?û¢-+Ä¢-VÄ¢-oÆ¢-8æ¢-bÉ¢-ôÿ¢-+Ä¢-?Ö¢-sÉ¢-ÜÖ¢-¦ö¢-=Æ¢-8æ¢-uô¢-=Æ¢-\\Å¢-uô¢-?ü¢-}¦¢-=Æ¢-)...

The format is real 32 which uses four bytes to store each value. The number #42404 represents 4 extra bytes present and 2404/4 = 601 points collected. The data starts after #42404. Now when I receive this into a string variable,

$lp = ibqry($ud,":TRAC:DATA? TRACE1;*WAI;");

I am not sure how to convert this into an array of numbers :(... Should I use something like the followin?

@dec = unpack("d", $lp);

I know this is not working, because I am not getting the right values and the number of data points for sure is not 601...

First, you have to strip the #42404 off and hope none of the following binary data happens to be an ASCII number.

$lp =~ s{^#\d+}{};

I'm not sure what format "Real 32" is, but I'm going to guess that it's a single precision floating point which is 32 bits long. Looking at the pack docs . d is "double precision float", that's 64 bits. So I'd try f which is "single precision".

@dec = unpack("f*", $lp);

Whether your data is big or little endian is a problem. d and f use your computer's native endianness. You may have to force endianness using the > and < modifiers.

@dec = unpack("f*>", $lp);  # big endian
@dec = unpack("f*<", $lp);  # little endian

If the first 4 encodes the number of remaining digits ( 2404 ) before the floats, then something like this might work:

my @dec = unpack "x a/x f>*", $lp;

The x skips the leading # , the a/x reads one digit and skips that many characters after it, and the f>* parses the remaining string as a sequence of 32-bit big-endian floats. (If the output looks weird, try using f<* instead.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM