Convert decimal number to hexadecimal in perl in specific format - perl

initialize a scalar variable with an integer value
my $dec = 1211;
print "Hexadecimal number: ", uc(sprintf("%x\n", $dec)), "\n";
displays 4BB
But how can i get the output in 000004BB ormat.

Use a length specifier with leading zeroes:
sprintf('%08X', $dec)
Also, you don't need to use the uc() function: just use the %X (capital-X) format character.
To print the heading as well:
printf "Hexadecimal number: %08X\n", $dec

Related

How to print a 4 digit hexadecimal value in Perl?

my $hex = sprintf('%X', oct("0b$reverse_str"));
print FOUT "HEX FORMAT: $hex\n";
If the hexa value is 007E, it is printing only 7E. How to get a 4 bit hexa value printed in Perl?
You have to use %04X instead of %X.

Converting to hexadecimal value in Perl

The following code:
$tmp1 = $_;
print "tmp1 is $tmp1";
$tmp1_hex = hex($tmp1);
print "tmp1_hex is $tmp1_hex\n";
$Lat_tmp1 = ($tmp1_hex >> 8) &0x00ff;
prints:
tmp1 is 0018
tmp1_hex is 24
The text file I'm reading the data from contains the string 0018, but when I convert it to the hex value I shouldn't be receiving 24.
If you want to convert to hex rather than from hex, use sprintf:
my $tmp1_hex = sprintf '%x', $tmp1;
The hex function merely interprets the string as a number in hexadecimal form. Beyond that, it's just a number and its original representation doesn't matter.
When you print a number, Perl uses its internal format (%g) to show it. That's a normal, decimal float.
If you want to output the number as something other than Perl's internal format, use printf and the appropriate specifier:
printf '%x', $number;
You probably want something like:
my $tmp1 = '0018';
print "tmp1 is $tmp1\n";
my $tmp1_hex = hex( $tmp1 );
printf "tmp1_hex is %x\n", $tmp1_hex;
Note that the bitwise operators don't need you to convert the number to any particular base. The number is the same number no matter how you display it.
The function hex() converts from hex to decimal. Try something like this instead
$tmp=$_;
$tmp1_hex=sprintf("%X",$tmp);

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
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.
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
$
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?
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.

Adding hex values in a loop

I have to generate a text file which contains a lot of hexadecimal values. The hex values are in arithmetic progression, with a difference of 0x1000000.
The output in the file should be as:
sum(0x08000000, "text")
sum(0x09000000, "some other text")
sum(0x0A000000, "yet another text")
...
sum(0x10000000, "random something")
...
Is there any way I can run a loop to generate these values?
Thanks.
You need printf or sprintf for outputting hex.
Perl "understands" hex just fine, if you stick 0x in front of it, it's hex.
For output formatting though, it'll default to 'normal' numeric representation - so instead you want either printf or sprintf (they do the same thing, but the latter 'prints' to a string).
#!/usr/bin/env perl
use strict;
use warnings;
print 0x10,"\n";
my $value = 0x20;
$value += 0x1F;
print $value,"\n";
printf ("%X\n", $value);
The format string is either %X for upper case hex, or %x to use lowercase.
So for your example:
for ( my $i = 0x8000000; $i <= 0x10000000; $i += 0x1000000 ) {
printf( "sum 0x%x\n", $i );
}

How do I get a checksum from unpack in hexadecimal format?

I've been trying to figure out the unpack function in Perl and can't quite figure out the whole thing.
What I have:
A string and a 16-bit hex checksum
(e.g. "this is my string", "0671")
I need to check that "this is my string" equals the checksum '0671'.
So I know unpack("%16W*", $string) will give me the 16-bit decimal value, but I need the hex representation. I know this is an easy one so please forgive my ignorance.
As you said, unpack("%16W*", $string) gives you an integer. To convert an integer to hex, use sprintf:
my $string = "this is my string";
my $expected = '0671';
my $checksum = sprintf('%04x', unpack("%16W*", $string));
print "match\n" if $checksum eq $expected;
If you want upper-case hex digits, use %X instead of %x (or %04X in this case).
Or, you could go the other way and convert your hex checksum to an integer using hex:
my $string = "this is my string";
my $expected = '0671';
my $checksum = unpack("%16W*", $string);
print "match\n" if $checksum == hex $expected; # now using numeric equality
Try unpack("b*',$string).
See the pack man page for syntax.