Hi
I am trying to parse a file in perl and decode a HEX code.
Ex:

0x0001
0x0002
0x0003
.
.
.
0xFFFF

I need to convert these hex to binary and make decision based on it.
0x0001 - 0000 0000 0000 0001
0x0003 - 0000 0000 0000 0011
0x0007 - 0000 0000 0000 0111
.
0xFFFF - 1111 1111 1111 1111

Any idea how to code this inteligently without doing 255 if/elsif statements? So like when there are 15 0s and only 1 1 then I do { x }
if 14 0s and 2 1s then { }
if 13 0s and 3 1s then { }
..
if 0 0s and 16 1s then { }

Thanks in advance

I don't understand why you need to convert the hex number into binary before using it to make a decision. Are these two separate requirements? You need to convert the string to binary AND you need to test the value and take one of 255 possible actions?

For your first question, there appears to be a solution that does something close to what you want here but I don't know how to break the resulting string into 4-character pieces separated by spaces.

For your second question: using a hash can often serve as an alternative to a long if-else-if statement. You could build a hash with 255 key-value pairs where the value is either a reference to a named subroutine or a string representing a block of code which you can eval() . The key of one of the hash entries would correspond with the string you read from the file. I mean something like the following:

#!/usr/bin/perl
use strict;
use warnings;
my %h; #Hash to store 255 (slightly) different pieces of perl code

foreach(0x1..0xFFFF){
    $h{$_} = qq(print 'Let us decide to take action number ', $_, "\n");
}

while (<DATA>){
    chomp;
    eval($h{hex($_)});
}
__DATA__
0x0009
0x0004
0x0007
0x00AA
0xFFFF

This gives the following output:

Let us decide to take action number 9
Let us decide to take action number 4
Let us decide to take action number 7
Let us decide to take action number 170
Let us decide to take action number 65535

d5e5

i am bit lost. How will i take the action if I dont know how many 1's are there.
I need to take specific actions depending on the number of 1's in the 16bit binary string.

In the foreach loop how will I know which number I am processing?

Thanks for your help. I am stuck doing thing.

What is it you have to "do" with each binary number. What is the content/function of the then{}? That makes a huge difference. I feel you have given us only 1/2 the problem. I mean, suppose a binary AND or OR or XOR would work? You haven't told us what you're going to do with the binary, only that you have a hex number and want a binary. Why do you need the spaces in the binary numbers?

Here's a quick hex to 16 bit binary conversion BTW:

use strict;
while(<DATA>){	
	my $bin=sprintf '%016b', hex($_);
	print "$bin\n";
}
__DATA__
0x0009
0x0004
0x0007
0x00AA
0xFFFF
Comments
That's a better one than what I could find. I was struggling with how to put the leading zeros.

I need to take specific actions depending on the number of 1's in the 16bit binary string.

I want to make sure I understand this requirement correctly. You mean that you would take the same action for 0x0003 as you would for 0x0005, because the binary strings that correspond to them both contain two 1's? If so, your script could count the ones something like this:

#!/usr/bin/perl
#count_ones_in_hex.pl
use strict;
use warnings;

while(<DATA>){
        chomp;
    my $bin=sprintf '%016b', hex($_);
        my $count_ones = my @ones = $bin =~ m/1/g;
    print "$bin has $count_ones one(s)\n";
}

__DATA__
0x0001
0x0002
0x0003
0x0004
0x0005
0x0006
0xFFFF

Edited 6 Years Ago by d5e5: Added code

If you really need spaces in the binary string, you can add them like this:

#!/usr/bin/perl
use strict;
use warnings;
my %h;
while(<DATA>){
        chomp;
        my $bin=sprintf '%016b', hex($_);
        my @groups = $bin =~ m/(\d{4})(\d{4})(\d{4})(\d{4})/g;
        print "$_ - " . join(' ', @groups) . "\n";
}

__DATA__
0x0001
0x0002
0x0003
0x0004
0x0005
0x0006
0xFFFF

That gives you the following output

0x0001 - 0000 0000 0000 0001
0x0002 - 0000 0000 0000 0010
0x0003 - 0000 0000 0000 0011
0x0004 - 0000 0000 0000 0100
0x0005 - 0000 0000 0000 0101
0x0006 - 0000 0000 0000 0110
0xFFFF - 1111 1111 1111 1111
This article has been dead for over six months. Start a new discussion instead.