SLP
SLP

Reputation: 305

Perl - convert hexadecimal to binary and use it as string

I am new to Perl and I have difficulties using the different types.

I am trying to get an hexadecimal register, transform it to binary, use it a string and get substrings from the binary string.

I have done a few searches and what I tried is :

my $hex = 0xFA1F;
print "$hex\n";

result was "64031" . First surprise : can't I print the hex value in Perl and not just the decimal value ?

$hex = hex($hex);
print "$hex\n";

Result was 409649. Second surprise : I would expect the result to be also 64031 since "hex" converts hexadecimal to decimal.

my $bin = printf("%b", $hex);

It prints the binary value. Is there a way to transform the hex to bin without printing it ?

Thanks, SLP

Upvotes: 5

Views: 3651

Answers (4)

stevieb
stevieb

Reputation: 9296

If you're ok with using a distribution, I wrote Bit::Manip to make my prototyping a bit easier when dealing with registers (There's also a Pure Perl version available if you have problems compiling the XS code).

Not only can it fetch out bits from a number, it can toggle, clear, set etc:

use warnings;
use strict;

use Bit::Manip qw(:all);

my $register = 0xFA1F;

# fetch the bits from register using msb, lsb

my $msbyte = bit_get($register, 15, 8);

print "value: $msbyte\n";

print "bin: " . bit_bin($msbyte) . "\n";

# or simply:
# printf "bin: %b\n", $msbyte;

Output:

value: 250
bin: 11111010

Here's a blog post I wrote that shows how to use some of the software's functionality with an example datasheet register.

Upvotes: 2

stack0114106
stack0114106

Reputation: 8711

You are assigning a integer value using hexadecimal format. print by default prints numbers in decimal format, so you are getting 64031.

You can verify this using the printf() by giving different formats.

$ perl -e ' my $num = 0xFA1F; printf("%d %X %b\n", ($num) x 3 ) '
64031 FA1F 1111101000011111

$ perl -e ' my $num = 64031; printf("%d %X %b\n", ($num) x 3 ) '
64031 FA1F 1111101000011111

$ perl -e ' my $num = 0b1111101000011111; printf("%d %X %b\n", ($num) x 3 ) '
64031 FA1F 1111101000011111

$

To get the binary format of 0xFA1F in string, you can use sprintf()

$ perl -e ' my $hex = 0xFA1F; my $bin=sprintf("%b",$hex) ; print "$bin\n" '
1111101000011111

$

Upvotes: 3

ikegami
ikegami

Reputation: 385789

Decimal, binary, and hexadecimal are all text representations of a number (i.e. ways of writing a number). Computers can't deal with these as numbers.

my $num = 0xFA1F; stores the specified number (sixty-four thousand and thirty-one) into $num. It's stored in a format the hardware understands, but that's not very important. What's important is that it's stored as a number, not text.

When print is asked to print a number, it prints it out in decimal (or scientific notation if large/small enough). It has no idea how the number of created (from a hex constant? from addition? etc), so it can't determine how to output the number based on that.

To print an number as hex, you can use

my $hex = 'FA1F';   # $hex contains the hex representation of the number.
print $hex;         # Prints the hex representation of the number.

or

my $num = 0xFA1F;   # $num contains the number.
printf "%X", $num;  # Prints the hex representation of the number.

Upvotes: 4

JGNI
JGNI

Reputation: 4013

lets take each bit of confusion in order

my $hex = 0xFA1F;

This stores a hex constant in $hex, but Perl doesn't have a hex data type so although you can write hex constants, and binary and octal constants for that matter, Perl converts them all to decimal. Note that there is a big difference between

my $hex = 0xFA1F;

and

my $hex = '0xFA1F';

The first stores a number into $hex, which when you print it out you get a decimal number, the second stores a string which when printed out will give 0xFAF1 but can be passed to the hex() function to be converted to decimal.

$hex = hex($hex);

The hex function converts a string as if it was a hex number and returns the decimal value and, as up to this point, $hex has only ever been used as a number Perl will first stringify $hex then pass the string to the hex() function to convert that value from hex to decimal.

So to the solution. You are almost there with printf(),there is a function called sprintf() which takes the same parameters as printf() but instead of printing the formatted value returns it as a string. So what you need is.

my $hex = 0xFA1F;
my $bin = sprintf("%b", $hex);
print $bin;

Technical note: Yes I know that Perl stores all its numbers internally as binary, but lets not go there for this answer, OK?

Upvotes: 2

Related Questions