Sorry. Let me try to clarify. I am trying to convert 8-character hex values to their 32-bit integer representation.
Actually, what you are trying to do is convert an 8 character hex string to a 32-bit SIGNED integer, at least according to the specification from Java or C. The problem you have is that there is no such thing as a strictly 32-bit integer in perl, so you must code the rules yourself or use a module as Jeff suggested.
Fortunately, the rules are fairly simple. But let's start with unsigned first:
unsigned int
Dec: 0 to 4_294_967_295 (2^32-1)
Hex Representation: 0x00000000 to 0xFFFFFFFF
As you can see, straight forward enough. And the hex translation can be handled directly with the
hex function and
sprintf.
Signed integers are a little harder. The positive range is handled easily enough. However, the negative range is indicated by the 32nd bit, and the values are stored opposite of the positive range. This made arithmetic simpler back in the "old days" I suspect.
signed int
Dec: (-1 * 2 ^ 31) -2_147_483_648 to 2_147_483_647 (2 ^ 31 - 1)
hex positive: 0x00000000 to 0x7FFFFFFF
hex negative: 0xFFFFFFFF to 0x80000000
The easiest way to code your own translation function would be to rely on a little bit arithmetic:
-
print hexstr_to_signed32int('FFFFFFCE'), "\n"; # Outputs -50
-
print signed32int_to_hexstr(-50), "\n"; # Outputs ffffffce
-
-
sub hexstr_to_signed32int {
-
my ($hexstr) = @_;
-
die "Invalid hex string: $hexstr"
-
if $hexstr !~ /^[0-9A-Fa-f]{1,8}$/;
-
-
my $num = hex($hexstr);
-
return $num >> 31 ? $num - 2 ** 32 : $num;
-
}
-
-
sub signed32int_to_hexstr {
-
my ($num) = @_;
-
die "Number outside of signed 32-bit range: $num"
-
if $num > 2_147_483_647 or $num < -2_147_483_648;
-
-
my $unsigned = $num < 0 ? 2 ** 32 + $num : $num;
-
return sprintf "%x", $unsigned;
-
}
-
If you wanted capital hex strings, just change %x to %X
- Miller