Reputation: 53
I am developing a script that convert collected HEX ( I don't know the Bit format of them) values to Decimal Values.
One of the example is the hex value: fef306da If I convert it, I receive 4277339866.
Website where I found the expected value (Decimal from signed 2's complement:): https://www.rapidtables.com/convert/number/hex-to-decimal.html
Do you guys have a solution how can I convert hex fef306da to decimal -17627430. Note: I get wrong value conversion when I convert hex that have (-)negative sign when decimal.
Thanks all!
Upvotes: 2
Views: 873
Reputation: 385546
You could use pack
my $hex = "fef306da";
my $num = hex($hex);
$num = unpack("l", pack("L", $num));
say $num; # -17627430
or
my $hex = "fef306da";
$hex = substr("00000000$hex", -8); # Pad to 8 chars
my $num = unpack("l>", pack("H8", $hex));
say $num; # -17627430
But simple arithmetic will do.
my $hex = "fef306da";
my $num = hex($hex);
$num -= 0x1_0000_0000 if $num >= 0x8000_0000;
say $num; # -17627430
Upvotes: 1
Reputation: 6798
If you interested in binary conversion then check following code (fef306da
is 32bit number)
use strict;
use warnings;
use feature 'say';
my $input = 'fef306da';
my $hex = hex($input);
my $dec;
if( $hex & 0x80000000 ) {
$dec = -1 * ((~$hex & 0x7fffffff)+1);
} else {
$dec = $data;
}
say $dec;
Output
-17627430
Tip: Two's complement
Upvotes: 1
Reputation: 1542
Look at pack and use modifiers for unsigned and signed values.
my $hex_value = "fef306da";
my $output_num = unpack('l', pack('L', hex($hex_value)));
print $output_num; ## -17627430
Perform a test on each hex value to determine if it is a 16bit or 32bit value. Then use the correct modifier with pack for long or short values.
Upvotes: 3
Reputation: 1375
it seems that you expect your decimal to be 32bit signed integer, but HEX($n) returns a 64bit one so you may try repack it
perl -e 'print unpack "l", pack "L", hex( "fef306da" )'
Upvotes: 3