Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Comparing packed variables

by Jaap (Curate)
on Mar 17, 2021 at 23:12 UTC ( #11129856=perlquestion: print w/replies, xml ) Need Help??

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

Is it possible to compare packed variable sin a meaningful way in perl?
I have some binary data in files, some files have uint8's others uint16 etc.
I'm trying to search for values in a certain range.
If possible i'd like to avoid having to unpack all that binary data.
print pack("S", 253) cmp pack("S", 254) => -1 print pack("S", 253) cmp pack("S", 257) => 1
Why does it only work for values up to 8 bits?
The 'S' is supposed to make unsigned 16-bit values.
Does this have to do with endian-ness? (i'm on x86-64)

Replies are listed 'Best First'.
Re: Comparing packed variables
by GrandFather (Saint) on Mar 17, 2021 at 23:26 UTC

    Yes:

    use strict; use warnings; for my $pair([253, 254], [253, 257]) { my $result = pack("S<", $pair->[0]) cmp pack("S<", $pair->[1]); print "Little: $pair->[0] cmp $pair->[1] = $result\n"; $result = pack("S>", $pair->[0]) cmp pack("S>", $pair->[1]); print "Big: $pair->[0] cmp $pair->[1] = $result\n"; $result = pack("S", $pair->[0]) cmp pack("S", $pair->[1]); print "Native: $pair->[0] cmp $pair->[1] = $result\n"; }

    Prints:

    Little: 253 cmp 254 = -1 Big: 253 cmp 254 = -1 Native: 253 cmp 254 = -1 Little: 253 cmp 257 = 1 Big: 253 cmp 257 = -1 Native: 253 cmp 257 = 1
    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      Ah like that.
      Is this a bug in Perl?
      My data is already in native/little endian-ness so i cannot compare it with packed variables?

        No, it's not a bug. String compare works from lowest memory address (first byte) to highest comparing one byte from each string at a time. Little endian puts the least significant byte in lowest memory so the two lowest bytes are compared first which is exactly backwards to what you want.

        Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: Comparing packed variables
by Tux (Canon) on Mar 18, 2021 at 08:30 UTC

    GrandFather is spot-on!

    To steal a sheet from a talk I did many years ago:

    use Data::Peek; foreach my $b (qw{ i I s S l L j J n N v V q Q }) { foreach my $e ("", "!", "<", ">") { $e =~ m{[<>]} && $b =~ m/[cCnNvV]/ and next; $e =~ m{[!]} && $b =~ m/[jJqQ]/ and next; my $f = "$b$e"; print STDERR "$f\t"; DHexDump pack $f => 0x1234567; } }

    ==>

    i686 Core(TM) i7-2620M x86_64 Xeon(R) E5320 ia64 Itanium + 2 === ======================== ======================== ============== +========== i 67 45 23 01 67 45 23 01 01 23 45 67 i! 67 45 23 01 67 45 23 01 01 23 45 67 i< 67 45 23 01 67 45 23 01 67 45 23 01 i> 01 23 45 67 01 23 45 67 01 23 45 67 I 67 45 23 01 67 45 23 01 01 23 45 67 I! 67 45 23 01 67 45 23 01 01 23 45 67 I< 67 45 23 01 67 45 23 01 67 45 23 01 I> 01 23 45 67 01 23 45 67 01 23 45 67 s 67 45 67 45 45 67 s! 67 45 67 45 45 67 s< 67 45 67 45 67 45 s> 45 67 45 67 45 67 S 67 45 67 45 45 67 S! 67 45 67 45 45 67 S< 67 45 67 45 67 45 S> 45 67 45 67 45 67 l 67 45 23 01 67 45 23 01 01 23 45 67 l! 67 45 23 01 67 45 23 01 00 00 00 00 00 00 00 00 01 + 23 45 67 l< 67 45 23 01 67 45 23 01 67 45 23 01 l> 01 23 45 67 01 23 45 67 01 23 45 67 L 67 45 23 01 67 45 23 01 01 23 45 67 L! 67 45 23 01 67 45 23 01 00 00 00 00 00 00 00 00 01 + 23 45 67 L< 67 45 23 01 67 45 23 01 67 45 23 01 L> 01 23 45 67 01 23 45 67 01 23 45 67 j 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 00 00 00 00 01 + 23 45 67 j< 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 67 45 23 01 00 + 00 00 00 j> 00 00 00 00 01 23 45 67 00 00 00 00 01 23 45 67 00 00 00 00 01 + 23 45 67 J 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 00 00 00 00 01 + 23 45 67 J< 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 67 45 23 01 00 + 00 00 00 J> 00 00 00 00 01 23 45 67 00 00 00 00 01 23 45 67 00 00 00 00 01 + 23 45 67 n 45 67 45 67 45 67 n! 45 67 45 67 45 67 N 01 23 45 67 01 23 45 67 01 23 45 67 N! 01 23 45 67 01 23 45 67 01 23 45 67 v 67 45 67 45 67 45 v! 67 45 67 45 67 45 V 67 45 23 01 67 45 23 01 67 45 23 01 V! 67 45 23 01 67 45 23 01 67 45 23 01 q 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 00 00 00 00 01 + 23 45 67 q< 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 67 45 23 01 00 + 00 00 00 q> 00 00 00 00 01 23 45 67 00 00 00 00 01 23 45 67 00 00 00 00 01 + 23 45 67 Q 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 00 00 00 00 01 + 23 45 67 Q< 67 45 23 01 00 00 00 00 67 45 23 01 00 00 00 00 67 45 23 01 00 + 00 00 00 Q> 00 00 00 00 01 23 45 67 00 00 00 00 01 23 45 67 00 00 00 00 01 + 23 45 67

    Enjoy, Have FUN! H.Merijn
Re: Comparing packed variables
by Anonymous Monk on Mar 18, 2021 at 15:42 UTC
    Unless you are avoiding "unpack" for demonstrable performance reasons, an argument for using it might be "clarity" and "future-proofing." This will first make it clear to the reader how the binary data is formatted, then make it clear how the elements that have been unpacked from it are being compared. And the code would be easier to read and harder to (accidentally ...) break.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11129856]
Approved by GrandFather
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2021-09-19 01:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?