Question

I have a large hex number - $num = 0x80000000, as a string. I want to increment it, but doing hex($num) does not work, due to integer overflow (comes out negative). using bigint is also not an option as hex with bigint is only implemented in perl 5.10 and beyond, I have 5.8. how can I ++ this string?

Was it helpful?

Solution 2

I have no issues with this using Perl 5.8.9 via Perlbrew:

#! /usr/bin/env perl
use strict;
use warnings;
my $num = 0x80000000;
print "$num\n";  # No quotes make this a number and not a string

This prints out 2147483648 which is the decimal value of 0x8000000.

What platform are you on?

What you probably want to do is to print out this hex number in hex and not decimal. You can still use ++ to increment it, but to print it out in hex, you need printf:

#! /usr/bin/env perl
#
use strict;
use warnings;
use Data::Dumper;

my $num = 0x80000000;

for my $loop (0..100) {
    $num++;
    printf "%-20x\n",  $num;
}

This prints out:

80000001            
80000002            
80000003            
80000004            
80000005            
80000006            
80000007            
80000008            
80000009            
8000000a
...

If indeed 0x80000000 is a string, using hex on my system using Perl 5.8.9 has no problem converting it into a number.

#! /usr/bin/env perl
use strict;
use warnings;
my $num = "0x80000000";  # This is a string
$num = hex $num;         # Now it's a number

print "$num\n";          # Prints 2147483648 because `$num` is numeric

As I said. This is Perl 5.8.9 (I can't get 5.8.8 on Perlbrew), and this is on a Mac. Maybe your platform is a wee bit different. Is it an old Solaris system with a 32bit version of SunOS or Solaris?

I've checked the 5.8.8 documentation and notice that the standard distribution does have Bigint support built in. It also comes with the module Math::Bigint too.

Are you sure you don't have Bigint support?

OTHER TIPS

Don't confuse the literal representation with the number with the actual value. When you make the assignment, no matter how you represented it, Perl ends up storing a number and no longer cares about the original representation. Use the normal numeric operations on it. When you want to look at it again, you can choose any of the representations you like:

$num = 0x8000000;
$num++;
printf "%0x" $num;

You only need hex() if you're getting your numeric representation as a string, like you would from a command line argument. You only need hex to turn the string into a number. After that, it's the same.

$num = hex( '8000000' );   # or hex( '0x8000000' )
# $num = hex( $ARGV[0] );
$num++;
printf "%0x" $num;

For the other part of your question, bignum works just fine on Perl v5.8:

$ perl5.8.9 -le 'my $i = 0xFFFFFFFF_FFFFFFFF; $i++; print $i'
1.84467440737096e+19
$ perl5.8.9 -Mbignum -le 'my $i = 0xFFFFFFFF_FFFFFFFF; $i++; print $i'
18446744073709551616
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top