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

I'm having some trouble manipulating 64-bit values in Perl. `perl -V` confirms that I am running perl 5.6.1 with USE_64_BIT_INT and USE_64_BIT_ALL on Tru64 UNIX. I believe what I am seeing is that whenever I do a comparison or any arithmetic, perl with translate the value to a floating point number, losing the precision that I need. (Bit manipulation operators are okay)

As a work around, I wind up manipulating the number as two 32-bit quantities. However, this is much slower, and, IMNSHO, quite ridiculous.

Below is a script and it's output illustrating what I am describing:

$ ./foo.pl A) 0xfffffc0123456789 (should be 0xfffffc0123456789) B) 0xfffffc0123456800 (should be 0xfffffc0123456789) C) 0xfffffc0123456789 (should be 0xfffffc0123456789) D) 0xfffffc0123456800 (should be 0xfffffc0123456788 or maybe 0xfffffc0 +123456790) E) 0x23456789 (should be 0x23456789) F) 0xfffffc01 (should be 0xfffffc01) G) Comparing 0xfffffc0123456789 to 0xfffffc0123456785: 1) 0 (should be 1) 2) 0 (should be -1) 3) 0 (should be 0) $ $ cat foo.pl #!/usr/local/bin/perl $a = 0xfffffc0123456789; printf "A) %#x (should be 0xfffffc0123456789)\n", $a; $str = "0xfffffc0123456789"; printf "B) %#x (should be 0xfffffc0123456789)\n", hex($str); $b = unpack "Q", (pack "L2", hex(substr($str, 10)), hex(substr($str, 2 +, 8))); printf "C) %#x (should be 0xfffffc0123456789)\n", $b; printf "D) %#x (should be 0xfffffc0123456788 or maybe 0xfffffc01234567 +90)\n", $a - 1; printf "E) %#x (should be 0x23456789)\n", $a & 0xffffffff; printf "F) %#x (should be 0xfffffc01)\n", $a >> 32; $b = 0xfffffc0123456785; printf "G) Comparing %#x to %#x:\n", $a, $b; printf " 1) %d (should be 1)\n", $a <=> $b; printf " 2) %d (should be -1)\n", $b <=> $a; printf " 3) %d (should be 0)\n", $a <=> $a; $

Replies are listed 'Best First'.
Re: Manipulating 64-bit values
by Elian (Parson) on Jun 04, 2002 at 20:31 UTC
    Right, math operations through 5.6.x "promote" to floating point. If you've a 64-bit integer perl without longer (80 bit or more) floats, this is bad.

    What you need to do is do all your manipulation in a block with "use integer;" in effect. That'll stop perl from promoting.

      Excellent! This handles everything except for using hex() to convert the 64-bit quantity from a hexadecimal string. That, however, should be simple enough to deal with (though if you had any ideas on how to make "use integer" carry through, I'd be interested).

      This should make life much easier!

Re: Manipulating 64-bit values
by samtregar (Abbot) on Jun 04, 2002 at 21:00 UTC
    You might try using 5.8.0 RC1. Changes were made in 5.8.0 to attempt to preserve integers whenever possible. 5.6.1 and earlier will "promote" integers to floating point even when that will cause a loss of precission.

    -sam

      Thanks for the help, sam. I thought about trying out 5.8.0; I'm glad to hear that the behavior may have improved. However, I think I'll use the 'use integer' solution until most of my expected user base has moved to 5.8.0. I appreciate your help.