youhaveaBigego
youhaveaBigego

Reputation: 85

Why does my unpack print the wrong values?

Why do I get the wrong answers/values?

The correct values it should print are 1, 2175, 4 but instead I always get 1, 3, 0 ?!

my $data = pack ('C*', map hex, split /\s+/, "01 00 00 00 7F 08 03 00 21 04 80 04 FF D7 FB 0C EC 01 44 00 61 1D 00 00 10 3B 00 00 FF D7 FB 0C 00 00 8C 64 00 00 EC 45");

($obj->{Version}, $obj->{res1}, $obj->{EARFCN}, $tmp1, $obj->{res2}, $tmp2)=unpack("C C3 v C C V", $data);

$obj->{band} = ($tmp1 & 0xfc) >> 2;
print "\n".$obj->{Version};    # Should print 1
print "\n".$obj->{EARFCN};   # Should print 2175
print "\n".$obj->{band};      # Should print 4. Note: this is the first 6 bits from MSB of $tmp1.
print "\n";

Upvotes: 4

Views: 194

Answers (3)

ikegami
ikegami

Reputation: 385917

There's no pattern for 24-bit words. (Machines don't have such a type.) You could use either of the following snippets.

You want band to be the most significant 6 bits of a 16-bit word (y in yyyy yyxx xxxx xxxx). For that, use $_ >> 10.

(
   $obj->{Version},
   my $tmp0,
   $obj->{EARFCN},
   my $tmp1,
   $obj->{res2},
   my $tmp2
) = unpack("C a3 v C C V", $data);

$obj->{res1} = unpack("V", $tmp0."\x00");
$obj->{band} = $tmp1 >> 10;

or

(
   my $tmp0,
   $obj->{EARFCN},
   my $tmp1,
   $obj->{res2},
   my $tmp2
) = unpack("V v C C V", $data);

$obj->{Version} = $tmp0 & 0xFF;
$obj->{res1}    = $tmp0 >> 8;
$obj->{band}    = $tmp1 >> 10;

Upvotes: 0

youhaveaBigego
youhaveaBigego

Reputation: 85

I made two mistakes.

I should have used the a3 specifier instead of using C3. So, it should say:

unpack("C a3 v C C V", $data);

and also

$obj->{band} = ($tmp1 & 0xfc) >> 2; is indeed 0. and not 4.

Upvotes: 1

Jim Garrison
Jim Garrison

Reputation: 86774

Debug output:

  DB<1> $data = pack ('C*', map hex, split /\s+/, "01 00 00 00 7F 08 03 00 21 04 80 04 FF D7 FB 0C EC 01 44 00 61 1D 00 00 10 3B 00 00 FF D7 FB 0C 00 00 8C 64 00 00 EC 45")

  DB<2> x unpack("C C3 v C C V", $data)
0  1
1  0
2  0
3  0
4  2175
5  3
6  0
7  75498529

Pattern C3 outputs three unsigned bytes, not a string of length three.

I think you want a3 instead. See Perldoc pack()

Upvotes: 2

Related Questions