3

I want to write a perl script to parse text files with a lot of 64-bit integers in it. All integers are written in hex.

I need to

  • Read hexes from input
  • Compare 64-bit ints (<, =, >)
  • Subtract 64-bit ints
  • Output 64-bit hexes

I need to use 32-bit perl and I can't use any CPAN/external module (the script must be portable).

PS my perl is 5.8 (and this is minimal version which will be used for the script)

PPS bignum/ bigint errors:

$ perl -e 'use bignum; $_=hex("0x0000123412345678")'
Integer overflow in hexadecimal number at -e line 1.

$ perl -e 'use bigint; $_=hex("0x0000123412345678")'
Integer overflow in hexadecimal number at -e line 1.

PPPS: no from_hex here.

$ perl -e 'use Math::BigInt; $_=Math::BigInt->from_hex("0x0000123412345678");'
Can't locate object method "from_hex" via package "Math::BigInt" at -e line 1.

And no qw/hex/:

$ perl -e 'use bigint qw/hex/; $_=hex("0x0000123412345678")'
unknown option hex at /usr/lib/perl5/5.8/bigint.pm line...

PPPPS: but new() works:

$ perl -e 'use Math::BigInt; $_=Math::BigInt->new("0x0000123412345678"); print  $_->as_hex(),"\n";'
0x123412345678
osgx
  • 90,338
  • 53
  • 357
  • 513
  • 1
    per the error in your update. the `hex` function is only automatically upgraded by bignum in perl 5.9.4 or later. You need to either explicitly export the `hex` function (which will be global in your version of perl) or use the `Math::BigInt->from_hex(...)` function directly. – Eric Strom Sep 06 '11 at 21:02

2 Answers2

10

The core pragma bigint will let you transparently work with integers larger than your system can support. There are associated functions in the Math::BigInt core library to convert from and to a hex representation.

Eric Strom
  • 39,821
  • 2
  • 80
  • 152
  • I got "Integer overflow in hexadecimal number at" when I tried to use "`use bignum;`" – osgx Sep 06 '11 at 20:57
  • 2
    The pragma may be introducing too much magic and might be mangling some of your constants. Try using the `Math::BigInt->new(...)` constructor directly. – Eric Strom Sep 06 '11 at 20:59
  • How `Math::BigInt->new` will set the sign? – osgx Sep 06 '11 at 22:02
4

Math::Int64 gives access to native signed and unsigned 64-bit numbers. This is surely faster than possible alternative Math::BigInt.

It has hex conversion routines, and it overloads comparison and arithmetic operators, so it can do everything you asked for.

use Math::Int64 qw( hex_to_uint64 uint64_to_hex );
my $n1 = hex_to_uint64("200000000");
my $n2 = hex_to_uint64("300000000");
printf("n1 is %s equal to n2\n",     $n1 == $n2 ? "" : "not");
printf("n1 is %s less than n2\n",    $n1 <  $n2 ? "" : "not");
printf("n1 is %s greater than n2\n", $n1 >  $n2 ? "" : "not");
printf("0x%016s", uint64_to_hex($n2 - $n1));

Output:

n1 is not equal to n2
n1 is less than n2
n1 is not greater than n2
0x0000000100000000

The use of CPAN or lack thereof doesn't effect the portability of the script.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • The error is "`$ perl -e 'use Math::Int64; ' Can't locate Math/Int64.pm in @INC`". As it was said in question, I can't use CPAN. – osgx Sep 06 '11 at 22:03
  • @osgx, No, you said you couldn't use CPAN for portability reasons, witch is inherently false. – ikegami Sep 06 '11 at 22:04
  • In my case, the target PC has no CPAN (and internet) access at all and it is very hard to install some new module to it (there is no compiler at the target PC, as it is embedded; but there is a perl 5.8 on it). I can bring a single perl script, which will use no XS/C. – osgx Sep 06 '11 at 22:06
  • 2
    @osgx, That's not a portability issue, but it does make Math::BigInt a better answer for you. (Note that I don't actually know how portable Math::Int64 is, so there could actually be portability issues.) – ikegami Sep 06 '11 at 22:08
  • I mean portable in a bit unusual way. The target is not a x86/x86_64, so it is not about usual desktop/notebook portability between win/lin/mac and gcc/llvm/icc. Most C codes are not very portable for my case. I dont know this too, but there was last comment about adding support of mingw32/win, so I think it is truly unportable for me) – osgx Sep 06 '11 at 22:09