Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with 64 bit integers on Solaris

0 views
Skip to first unread message

Ajit Yashwant Vaishampayan

unread,
Sep 12, 2002, 10:11:40 AM9/12/02
to perl5-...@perl.org
Hello,

I have built the 64 bit Perl 5.6.1 and trying to use it for some programs. I
am having problem in following program

-------------------------------------------------------------------
BEGIN
{
print "================ Test no 1 ==================\n";
$a = 0x001fffffffffffff;
print "value of \$a : $a\n";
$c = $a++;
print "value of \$c : $c\n";
print "New value of \$a : $a\n";
if ($a == $c) {
print "Both \$a and \$c are same\n";
} else {
print "\$a and \$c are different\n";
}
print "=============================================\n";

print "================ Test no 2 ==================\n";
$a = 0x0020000000000000;
print "value of \$a : $a\n";
$c = $a++;
print "value of \$c : $c\n";
print "New value of \$a : $a\n";
if ($a == $c) {
print "Both \$a and \$c are same\n";
} else {
print "\$a and \$c are different\n";
}
print "=============================================\n";
}
------------------------------------------------------------------


This program is showing following output

================ Test no 1 ==================
value of $a : 9007199254740991
value of $c : 9007199254740991
New value of $a : 9007199254740992
$a and $c are different
=============================================
================ Test no 2 ==================
value of $a : 9007199254740992
value of $c : 9007199254740992
New value of $a : 9007199254740993
Both $a and $c are same
=============================================


But As per me in the Test no 2 also the numbers should be different. Can
anybody help me about this ?

Thanks,
Ajit

Nicholas Clark

unread,
Sep 14, 2002, 1:45:04 PM9/14/02
to Ajit Yashwant Vaishampayan, Noida, perl5-...@perl.org
On Thu, Sep 12, 2002 at 07:41:40PM +0530, Ajit Yashwant Vaishampayan, Noida wrote:
> Hello,
>
> I have built the 64 bit Perl 5.6.1 and trying to use it for some programs. I
> am having problem in following program

> This program is showing following output


>
> ================ Test no 1 ==================
> value of $a : 9007199254740991
> value of $c : 9007199254740991
> New value of $a : 9007199254740992
> $a and $c are different
> =============================================
> ================ Test no 2 ==================
> value of $a : 9007199254740992
> value of $c : 9007199254740992
> New value of $a : 9007199254740993
> Both $a and $c are same
> =============================================
>
>
> But As per me in the Test no 2 also the numbers should be different. Can
> anybody help me about this ?

regrettably perl5.6.1's INSTALL doesn't appear to make it clear precisely
what telling perl to 64 bit integers does do, and what it doesn't.

it says:

The C<use64bitint> does only as much as is required to get 64-bit
integers into Perl (this may mean, for example, using "long longs")
while your memory may still be limited to 2 gigabytes (because your
pointers could still be 32-bit). Note that the name C<64bitint> does
not imply that your C compiler will be using 64-bit C<int>s (it might,
but it doesn't have to): the C<use64bitint> means that you will be
able to have 64 bits wide scalar values.

The C<use64bitall> goes all the way by attempting to switch also
integers (if it can), longs (and pointers) to being 64-bit. This may
create an even more binary incompatible Perl than -Duse64bitint: the
resulting executable may not run at all in a 32-bit box, or you may
have to reboot/reconfigure/rebuild your operating system to be 64-bit
aware.


what it doesn't say is that perl is still using doubles to perform all
arithmetic. On Solaris (and almost everywhere) doubles are 64 bits long,
with 53 bits for the mantissa. 2**53 is 9007199254740992, so doubles can't
hold the low bits of values greater than that. Hence your 64 bit perl 5.6.1
has ++ adding 1.0 to 9007199254740992.0 (in floating point).
There aren't enough bits in the double to represent 9007199254740993, so
out of the two nearest representable values 9007199254740992.0 and
9007199254740994.0, you're getting back 9007199254740992.0

This isn't very helpful.

I believe your two options are

1: to do arithmetic on 64 bit 5.6.1 in the scope of use integer;
(which will tell perl to use integers for arithmetic operations and
comparisons),

2: to compile perl 5.8.0 for 64 bit integers. perl5.8.0 does what you were
expecting from 5.6.1, automatically using integers where both arguments
are integer and won't overflow, otherwise using floating point.
With a 64 bit perl 5.8.0 your test program gives

================ Test no 1 ==================
value of $a : 9007199254740991
value of $c : 9007199254740991
New value of $a : 9007199254740992
$a and $c are different
=============================================
================ Test no 2 ==================
value of $a : 9007199254740992
value of $c : 9007199254740992
New value of $a : 9007199254740993
$a and $c are different
=============================================

Nicholas Clark
--
Even better than the real thing: http://nms-cgi.sourceforge.net/

0 new messages