On Tuesday 17 May 2011 22:06:34 David Harkness wrote:
> It appears that PHP is truncating the constant 0x80000000 to be within
> MIN_INT and MAX_INT instead of as a bit field, but when shifting 1 << 31 it
> doesn't do apply any constraints. That's pretty typical of
> bit-manipulation: it will merrily slide 1 bits off either end. This
> explains why & produces 0 as it's doing 0x80000000 & 0x7FFFFFFF. It also
> explains the second tests.

Yes, that's it!
I slightly expanded test output and now it's clear that you are right:

$tst1 = (1 << 31);
$tst2 = 0x80000000;
$tst1_eq = $tst1 & 0x80000000;
$tst2_eq = $tst2 & 0x80000000;
$str1 = sprintf("%1$032b", $tst1);
$str2 = sprintf("%1$032b", $tst2);
print "tst1=$tst1 ($str1), tst1_eq=$tst1_eq, tst1_type=".gettype($tst1)."\n";
print "tst2=$tst2 ($str2), tst2_eq=$tst2_eq, tst2_type=".gettype($tst2)."\n";

produces this output:

tst1=-2147483648 (10000000000000000000000000000000), tst1_eq=0, 
tst2=2147483647 (01111111111111111111111111111111), tst2_eq=2147483647, 

Now it is obvious to me that PHP 5.2 clamps explicit constants to MAX_INT. 
Weird, brrrr...

> On 64-bit 5.3.3 I get
>     tst1=2147483648, tst1_eq=2147483648, tst1_type=integer
>     tst2=2147483648, tst2_eq=2147483648, tst2_type=integer
> If I try the 64-bit-equivalent code I get
>     tst1=-9223372036854775808, tst1_eq=-9223372036854775808,
> tst1_type=integer
>     tst2=9.22337203685E+18, tst2_eq=-9223372036854775808, tst2_type=double

I get similar results with 5.3 on my amd64 host too. It works as it should, no 
weirdness. Glad to know that 5.3 get it fixed. Pity to me that I can not 
update my 5.2 on ARM board.

Vitalii Demianets

PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to