http://qs1969.pair.com?node_id=184033

RollyGuy has asked for the wisdom of the Perl Monks concerning the following question:

I have a project that requires large integer constants. I need to be able to type them as constants in my perl code in hex.

I've explored the BigInt package and it will probably work, but one of my coworkers is pushing me to try 64-bit Perl. I'd like to know the preferred way to handle this situation. Is 64-bit Perl stable? Or is the BigInt package the best way to handle large integers?

Replies are listed 'Best First'.
Re: Big Numbers
by Abigail-II (Bishop) on Jul 22, 2002 at 13:50 UTC
    64-bit Perl is as stable as your platform/compiler is. But 64-bit integers means at that you are limited to the range -18446744073709551616 to 18446744073709551615, while Math::BigInt gives you virtually unlimited sized integers (you're only bound by the size of your virtual memory). Of course, 64 bit integers, whether native or simulated, are much, much, much faster than Math::BigInt integers.

    Abigail

      Actually, if you take signedness into consideration, only -2**63 .. (-2**63)-1 can be expressed, which is -9 223 372 036 854 775 808 to 9 223 372 036 854 775 807
      print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
Re: Big Numbers
by grinder (Bishop) on Jul 22, 2002 at 14:06 UTC
    2 raised to the 64th power is only 18 446 744 073 709 551 616, or around 18 and a half quintillion. Or about 16 exabytes. Which is fantistically huge, or woefully inadequate, depending on what your needs are.

    Math::BigInt lets you define numbers as  my $num = Math::BigInt->new( '18 446 744 073 709 551 617' ) which is as about as clean as it gets.

    Internally, the package uses base 10 arithmetic, not base 2 (or 16), which is why I suspect you can't enter numbers in hex format. I suppose no-one has got around to patching the package to do it. Converting between base 10 and base 16 is algorithmically fairly trivial but computationally quite expensive, as you have to perform repeated divisions. (Update: to be precise, converting from hex to dec is easy. I was thinking about converting from decimal to hex... unless there's something I've missed, you can't do it with lookup tables).

    Your easiest bet would be to write a program that takes an arbirtarily long hex string and converts it to base 10, and use that constant in your program. For extra credit, you could patch the Math::BigInt package to allow the 0x prefix to signify a hex representation, and have the package decode it.


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
      Repeated division? How come? Here's a simple routine that translates hex numbers into decimal ones. Replace the my $answer = 0; with my $answer = Math::BigInt -> new (0); to extend it bigger numbers.
      my $c = 0; my %X = map {$_ => $c ++} 0 .. 9, 'A' .. 'F'; sub hex2dec { local $_ = shift; my $answer = 0; ($answer <<= 4) += $X {substr $_ => 0, 1, ""} while length; $answer; }
      Abigail
      Thanks for the Math::BigInt link. I found that I was using an older version of the Math::BigInt package. I was using the autocreated constant feature where any constant in the current scope is converted into a BigInt. I had success with integers, but not hex values. The documentation now claims hex constants will be converted as well. All I have to do (according to the documentation) is:
      use Math::BigInt qw/:constant/;